package com.alibaba.citrus.ots.b2b.trade.order.facade.service;

import com.alibaba.citrus.ots.b2b.trade.order.facade.common.DateUtils;
import com.alibaba.citrus.ots.b2b.trade.order.facade.common.SetOrderTag;
import com.alibaba.citrus.ots.b2b.trade.order.facade.common.StringConverter;
import com.alibaba.citrus.ots.b2b.trade.order.functions.order.entity.OrderWriteEntity;
import com.alibaba.citrus.ots.b2b.trade.order.functions.order.factory.OrderWriteFactory;
import com.alibaba.citrus.ots.b2b.trade.order.functions.utils.SaveOrderConverter;
import com.alibaba.citrus.ots.b2b.trade.order.repository.OrderLineQueryServiceRepository;
import com.alibaba.citrus.ots.b2b.trade.order.repository.OrderLineWriteRepository;
import com.alibaba.citrus.ots.b2b.trade.order.repository.OrderQueryServiceRepository;
import com.alibaba.citrus.ots.b2b.trade.order.repository.OrderWriteRepository;
import com.alibaba.citrus.ots.common.annotation.EpochTransactional;
import com.alibaba.citrus.ots.common.annotation.FacadeInvoker;
import com.alibaba.citrus.ots.common.annotation.ProcessInvoker;
import com.alibaba.citrus.ots.common.constant.SaleOrderConstants;
import com.alibaba.citrus.ots.common.exception.FacadeException;
import com.alibaba.citrus.ots.common.exception.FunctionException;
import com.alibaba.citrus.ots.common.lock.RedisLock;
import com.alibaba.citrus.ots.common.lock.SaleRedisLock;
import com.alibaba.citrus.ots.common.log.ModuleEnum;
import com.alibaba.cz.base.tool.DateFormatUtil;
import com.alibaba.cz.base.tool.Nullable;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.base.tool.log.model.OpLogModel;
import com.alibaba.cz.base.tool.log.model.OperateType;
import com.alibaba.cz.base.tool.log.model.OperatorType;
import com.alibaba.cz.base.tool.page.PageResult;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.middleware.cache.runtime.service.EpochCacheService;
import com.alibaba.lattice2.epoch.middleware.mq.runtime.EpochMessageService;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcots.contants.BcOtsConstants;
import com.epoch.app.bcots.model.dto.*;
import com.epoch.app.bcots.platform_enhance.SaleOrderTag;
import com.epoch.app.bcots.service.BaseDataService;
import com.epoch.app.bcots.service.BcOtsService;
import com.epoch.app.bcots.service.UnifiedInventoryService;
import com.epoch.app.otsb2btradecenter.api.orderwrite.dto.ExcelImportOrderListRequest;
import com.epoch.app.otsb2btradecenter.api.orderwrite.dto.SapDeleteSaleOrderRequest;
import com.epoch.app.otsb2btradecenter.api.orderwrite.service.OrderWriteService;
import com.epoch.app.otsb2btradecenter.dto.OrderDetailDTO;
import com.epoch.app.otsb2btradecenter.dto.request.*;
import com.epoch.app.otsb2btradecenter.dto.request.OrderPageQueryRequest;
import com.epoch.app.otsb2btradecenter.dto.response.BatchCreateOrderResponse;
import com.epoch.app.otsb2btradecenter.dto.response.OrderPageQueryResponse;
import com.epoch.app.otsb2btradecenter.dto.response.OrderQueryResponse;
import com.epoch.app.otsb2btradecenter.enums.OrderStatus;
import com.epoch.app.otsb2btradecenter.model.dto.*;
import com.epoch.app.otsb2btradecenter.model.enums.OrderOperateType;
import com.epoch.app.otsb2btradecenter.sdo.OrderLineSDO;
import com.epoch.app.otsb2btradecenter.sdo.OrderSDO;
import com.epoch.app.otsb2btradecenter.sdo.PaymentInformationSDO;
import com.epoch.app.otsb2btradecenter.sdo.ScItemSDO;
import com.epoch.app.otsforecastsales.api.forecastorderlinequery.service.ForecastOrderLineQueryService;
import com.epoch.app.otsforecastsales.model.dto.QueryGoodsDetailForMiniprogrameRequest;
import com.epoch.app.otsforecastsales.model.dto.QueryGoodsDetailForMiniprogrameResponse;
import com.epoch.app.otsforecastsales.model.dto.QuerySaleUnitRequest;
import com.epoch.app.otsforecastsales.model.dto.SelectCombox;
import com.epoch.app.otsforecastsales.sdo.ForecastOrderLineSDO;
import com.epoch.app.otsforecastsales.service.OtsForecastSalesService;
import com.epoch.app.otsplatformenhance.api.customeraddressquery.service.CustomerAddressQueryService;
import com.epoch.app.otsplatformenhance.api.customerquery.service.CustomerQueryService;
import com.epoch.app.otsplatformenhance.api.group.scitemgroupquery.service.ScItemGroupQueryService;
import com.epoch.app.otsplatformenhance.api.organizationquery.dto.GetOrganizationsByOutCodesRequest;
import com.epoch.app.otsplatformenhance.api.organizationquery.service.OrganizationQueryService;
import com.epoch.app.otsplatformenhance.api.strategyquery.dto.QueryGenerateOrderSwitchRequest;
import com.epoch.app.otsplatformenhance.api.strategyquery.service.StrategyQueryService;
import com.epoch.app.otsplatformenhance.channel.service.ChannelService;
import com.epoch.app.otsplatformenhance.dto.request.CustomerAddressBatchRequest;
import com.epoch.app.otsplatformenhance.dto.request.CustomerRequest;
import com.epoch.app.otsplatformenhance.dto.request.QueryAddressRequest;
import com.epoch.app.otsplatformenhance.dto.request.QueryScItemGroupRequest;
import com.epoch.app.otsplatformenhance.dto.response.ScItemGroupResponse;
import com.epoch.app.otsplatformenhance.enums.OrganizationTypeEnum;
import com.epoch.app.otsplatformenhance.enums.StrategyTypeEnum;
import com.epoch.app.otsplatformenhance.model.dto.*;
import com.epoch.app.otsplatformenhance.sdo.CustomerAddressSDO;
import com.epoch.app.otsplatformenhance.sdo.CustomerSDO;
import com.epoch.app.otsplatformenhance.sdo.OrganizationSDO;
import com.epoch.app.otsplatformenhance.service.OtsPlatformEnhanceService;
import com.epoch.app.otsunifiedinventory.api.allocateorderread.service.AllocateOrderReadService;
import com.epoch.app.otsunifiedinventory.api.allocaterelationread.dto.QueryAllocateRelationForOrderRequest;
import com.epoch.app.otsunifiedinventory.api.allocaterelationread.service.AllocateRelationReadService;
import com.epoch.app.otsunifiedinventory.domain.allocateapplyorder.model.AllocateApplyOrder;
import com.epoch.app.otsunifiedinventory.domain.allocateapplyorder.service.AllocateApplyOrderService;
import com.epoch.app.otsunifiedinventory.domain.allocateapplyorderdetail.dto.AllocateApplyOrderDetailLoadListRequest;
import com.epoch.app.otsunifiedinventory.domain.allocateapplyorderdetail.model.AllocateApplyOrderDetail;
import com.epoch.app.otsunifiedinventory.domain.allocateapplyorderdetail.service.AllocateApplyOrderDetailService;
import com.epoch.app.otsunifiedinventory.domain.allocateorder.dto.AllocateOrderLoadListRequest;
import com.epoch.app.otsunifiedinventory.domain.allocateorder.dto.DeleteAllocateOrderRequest;
import com.epoch.app.otsunifiedinventory.domain.allocateorder.model.AllocateOrder;
import com.epoch.app.otsunifiedinventory.domain.allocateorder.service.AllocateOrderService;
import com.epoch.app.otsunifiedinventory.domain.allocateorderdetail.dto.AllocateOrderDetailLoadListRequest;
import com.epoch.app.otsunifiedinventory.domain.allocateorderdetail.dto.DeleteAllocateOrderDetailRequest;
import com.epoch.app.otsunifiedinventory.domain.allocateorderdetail.model.AllocateOrderDetail;
import com.epoch.app.otsunifiedinventory.domain.allocateorderdetail.service.AllocateOrderDetailService;
import com.epoch.app.otsunifiedinventory.dto.request.AllocateOrderDetailsQueryRequest;
import com.epoch.app.otsunifiedinventory.dto.response.AllocateOrderDetailsQueryResponse;
import com.epoch.app.otsunifiedinventory.model.dto.GetListWarehouseStockRequest;
import com.epoch.app.otsunifiedinventory.model.dto.WarehouseInventory;
import com.epoch.app.otsunifiedinventory.sdo.AllocateRelationSDO;
import com.epoch.app.otsunifiedinventory.sdo.enums.AllocateApplyOrderStatusEnum;
import com.epoch.app.otsunifiedinventory.sdo.enums.AllocateOrderTypeEnum;
import com.epoch.app.otsunifiedinventory.sdo.enums.AllocateStatusEnum;
import com.epoch.app.otsunifiedinventory.service.OtsUnifiedInventoryService;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Component
@Primary
public class OrderServiceImpl implements OrderWriteService {

    private static final Log log = Log.getLogger(OrderServiceImpl.class);


    @Autowired
    private BaseDataService baseDataService;
    @Resource
    private OrderQueryServiceRepository orderQueryServiceRepository;
    @Autowired
    private AllocateOrderReadService allocateOrderReadService;
    @Resource
    private OrderWriteRepository orderWriteRepository;
    @Resource
    private CustomerAddressQueryService customerAddressQueryService;
    @Resource
    private OrganizationQueryService organizationQueryService;
    @Resource
    private ChannelService channelService;
    @Resource
    private ScItemGroupQueryService scItemGroupQueryService;
    @Resource
    private CustomerQueryService customerQueryService;
    @Resource
    private OrderLineWriteRepository orderLineWriteRepository;
    @Resource
    private OrderLineQueryServiceRepository orderLineQueryServiceRepository;
    @Resource
    private BcOtsService bcOtsService;
    @Resource
    private UnifiedInventoryService unifiedInventoryService;
    @Resource
    private OtsUnifiedInventoryService otsUnifiedInventoryService;
    @Resource
    private ForecastOrderLineQueryService forecastOrderLineQueryService;
    @Resource
    private OtsForecastSalesService otsForecastSalesService;
    @Resource
    private StrategyQueryService strategyQueryService;
    @Resource
    private EpochMessageService messageService;
    @Resource
    private OtsPlatformEnhanceService otsPlatformEnhanceService;
    @Resource
    private AllocateRelationReadService allocateRelationReadService;
    @Resource
    private EpochCacheService epochCacheService;
    @Resource
    private AllocateOrderService allocateOrderService;
    @Resource
    private AllocateOrderDetailService allocateOrderDetailService;
    @Resource
    private  AllocateApplyOrderService allocateApplyOrderService;
    @Resource
    private AllocateApplyOrderDetailService allocateApplyOrderDetailService;

    private static final Pattern PATTERN_NUMERIC = Pattern.compile("^-{0,1}[0-9]+([.]{1}[0-9]+){0,1}$");

    private static final Pattern PATTERN_SPECIAL_STRING = Pattern.compile("[ _`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]|\n|\r|\t");

    @FacadeInvoker
    @EpochTransactional(appCode = "ots_b2b_trade_center", dataSourceCode = "cr_ots", dataSourceType = "app")
    @Override
    public Result<List<BatchCreateOrderResponse>> saveSaleOrder(SaveSaleOrderRequest request) {
        log.info("OrderServiceImpl SaveSaleOrderRequest:" + JSONObject.toJSONString(request));
        if (request == null) {
            log.error("创建销售订单入参为空");
            return Result.fail("OTS-05-001-10-16-028", "参数不能为空");
        }
        //获取当前登录人
        EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse = bcOtsService.employeeGetCurrentLogin();

        List<BatchCreateOrderResponse> batchCreateOrderResponsesNew = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(request.getOrderSDOS())) {
            List<OrderWriteEntity> orderWriteEntityList = OrderWriteFactory.createOrder(request);
            for (OrderWriteEntity orderWriteEntity : orderWriteEntityList) {
                List<BatchCreateOrderResponse> batchCreateOrderResponses = orderWriteEntity.batchSave();
                if (CollectionUtils.isNotEmpty(batchCreateOrderResponses)) {
                    for (BatchCreateOrderResponse response : batchCreateOrderResponses) {
                        OpLogModel.OpLogModelBuilder<String> builder = OpLogModel.builder();
                        OpLogModel<String> opLogModel = builder.build();
                        opLogModel.setModuleName(ModuleEnum.SALES.getModuleName());
                        opLogModel.setModuleId(String.valueOf(ModuleEnum.SALES.getModuleId()));
                        opLogModel.setObjectId(response.getOrderId());
                        opLogModel.setObjectName("so_order_id");
                        opLogModel.setOperateType(OrderOperateType.CREATE.getCode());
                        opLogModel.setOperatorType(OperatorType.USER.getOperatorType());
                        Map<String, String> map = new HashMap<>();
                        if (StringUtils.isNotBlank(employeeGetCurrentLoginResponse.getEmployeeId()) && StringUtils.isNotBlank(employeeGetCurrentLoginResponse.getEmployeeName())) {
                            opLogModel.setOperatorId(employeeGetCurrentLoginResponse.getEmployeeId());
                            map.put("name", employeeGetCurrentLoginResponse.getEmployeeName());
                            //opLogModel.setFeatures(employeeGetCurrentLoginResponse.getEmployeeName());
                        }
                        map.put("active", OrderOperateType.CREATE.getDesc());
                        String logInfo = JSONObject.toJSONString(map);
                        opLogModel.setFeatures(logInfo);
                        log.asyncMonitorObjectChangeV2(opLogModel);
                    }
                }
                batchCreateOrderResponsesNew.addAll(batchCreateOrderResponses);
            }
            return Result.success(batchCreateOrderResponsesNew);
        }
        BatchCreateOrderResponse response = new BatchCreateOrderResponse();
        OrderWriteEntity orderWriteEntity = OrderWriteFactory.saveSaleOrder(request);
        String id = orderWriteEntity.save();
        OpLogModel.OpLogModelBuilder<String> builder = OpLogModel.builder();
        OpLogModel<String> opLogModel = builder.build();
        opLogModel.setModuleName(ModuleEnum.SALES.getModuleName());
        opLogModel.setModuleId(String.valueOf(ModuleEnum.SALES.getModuleId()));
        opLogModel.setObjectId(id);
        opLogModel.setObjectName("id");
        opLogModel.setOperateType(OperateType.CREATE.getOperateType());
        opLogModel.setOperatorType(OperatorType.USER.getOperatorType());
        Map<String, String> map = new HashMap<>();
        if (Objects.nonNull(employeeGetCurrentLoginResponse)) {
            opLogModel.setOperatorId(employeeGetCurrentLoginResponse.getEmployeeId());
            map.put("name", employeeGetCurrentLoginResponse.getEmployeeName());
        }
        map.put("active", OrderOperateType.CREATE.getDesc());
        String logInfo = JSONObject.toJSONString(map);
        opLogModel.setFeatures(logInfo);
        log.asyncMonitorObjectChangeV2(opLogModel);
        response.setOrderId(id);
        batchCreateOrderResponsesNew.add(response);
        return Result.success(batchCreateOrderResponsesNew);
    }

    @Override
    @FacadeInvoker
    @EpochTransactional(appCode = "ots_b2b_trade_center", dataSourceCode = "cr_ots")
    public Result<Boolean> modifySaleOrder(ModifyOrderRequest request) {
        return modifySaleOrderV2(request);
        /*log.info("ModifyOrderRequest request :modifySaleOrder方法" + JSONObject.toJSONString(request));

        //获取当前登录人信息
        EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse = bcOtsService.employeeGetCurrentLogin();
        OrderQueryRequest queryRequest = new OrderQueryRequest();
        OrderQueryResponse query = null;
        if (null != request.getBaseInfo() && StringUtils.isNotBlank(request.getBaseInfo().getId())) {
            queryRequest.setId(request.getBaseInfo().getId());
            query = orderQueryServiceRepository.query(queryRequest);
        }
        //sap同步015
        if (StringUtils.isNotBlank(request.getOutOrderId())) {
            //添加缓存
//            if (epochCacheService.exists("REDIS_CACHE",request.getOutOrderId())) {
//                // todo 黔雷 需要优化为sleep 1s 等待更新
//                try {
//                    Thread.sleep(500L);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
////                return Result.success(true);
//            }
//            epochCacheService.put("REDIS_CACHE",request.getOutOrderId(),"",5L, TimeUnit.SECONDS);

            OrderPageQueryRequest pageQueryRequest = new OrderPageQueryRequest();
            PageResult<List<OrderPageQueryResponse>> listPageResult = null;
            if (StringUtils.isNotBlank(request.getTradeOrderId())) {
                pageQueryRequest.setId(request.getTradeOrderId());
                listPageResult = orderQueryServiceRepository.pageQuery(pageQueryRequest);
            }

            if (listPageResult == null || CollectionUtils.isEmpty(listPageResult.getContent())){
                OrderPageQueryRequest innerQuery = new OrderPageQueryRequest();
//                pageQueryRequest.setId(request.getTradeOrderId());
                pageQueryRequest.setOuterOrderId(request.getOutOrderId());
                listPageResult = orderQueryServiceRepository.pageQuery(innerQuery);
            }
            //查询不到就创建
            if (CollectionUtils.isEmpty(listPageResult.getContent())) {
                OrderSDO orderSDO = new OrderSDO();
                extracted(request, orderSDO);
                orderSDO.setCreatorName(request.getCreator());
                if (SaleOrderTag.LOGISTIC_RETURN_ORDER.getCode().equals(orderSDO.getOrderType())) {
                    orderSDO.setStatus(OrderStatus.WAIT_RECEIVING.getCode());
                }
                if (SaleOrderTag.STD_ORDER.getCode().equals(orderSDO.getOrderType())) {
                    orderSDO.setStatus(OrderStatus.BEFORE_DELIVERY.getCode());
                }
                SetOrderTag.getOrderTag(orderSDO.getOrderType(), orderSDO);
                orderSDO.getOrderLineSDOS().forEach(orderLineSDO -> {
                    orderLineSDO.setStatus(orderSDO.getStatus());
                    orderLineSDO.setOrderLineTag(orderSDO.getOrderTag());
                });
                OrderWriteEntity orderWriteEntity = OrderWriteFactory.saveOrderZRE3(orderSDO);
                List<BatchCreateOrderResponse> batchCreateOrderResponses = orderWriteEntity.batchSave();
                for (BatchCreateOrderResponse response : batchCreateOrderResponses) {
                    OpLogModel.OpLogModelBuilder<String> builder = OpLogModel.builder();
                    OpLogModel<String> opLogModel = builder.build();
                    opLogModel.setModuleName(ModuleEnum.SALES.getModuleName());
                    opLogModel.setModuleId(String.valueOf(ModuleEnum.SALES.getModuleId()));
                    opLogModel.setObjectId(response.getOrderId());
                    opLogModel.setObjectName("orderId");
                    opLogModel.setOperateType(OperateType.EDIT.getOperateType());
                    opLogModel.setOperatorType(OperatorType.USER.getOperatorType());
                    Map<String, String> map = new HashMap<>();
                    if (Objects.nonNull(employeeGetCurrentLoginResponse)){
                        map.put("name", employeeGetCurrentLoginResponse.getEmployeeName());
                    }
                    map.put("active", OrderOperateType.EDIT.getDesc());
                    String logInfo = JSONObject.toJSONString(map);
                    opLogModel.setFeatures(logInfo);
                    log.asyncMonitorObjectChangeV2(opLogModel);
                }
                //删除缓存
//                epochCacheService.remove("REDIS_CACHE",Collections.singletonList(request.getOutOrderId()));
                return Result.success(true);
            }

            queryRequest.setId(listPageResult.getContent().get(0).getId());
            query = orderQueryServiceRepository.query(queryRequest);
        }
        OrderSDO orderSDO = SaveOrderConverter.respConverterSDO(query);
        // 旧数据
        OrderSDO oldOrderSDO = SaveOrderConverter.respConverterSDO(query);

        if (request.getBaseInfo() != null) {
            //页面参数转换
            extracted1(request, orderSDO);
        } else {
            //015参数转换
            extracted(request, orderSDO);
            orderSDO.setModifierName(request.getCreator());
        }
        OrderWriteEntity orderWriteEntity = OrderWriteFactory.updateOrder(orderSDO);
        Result<Boolean> fag = orderWriteEntity.modify();
        //识别拒绝的子单并发送拒绝消息
        this.getRefusedId(oldOrderSDO,orderSDO);
        //根据订单状态进行活动回//删除缓存
//        epochCacheService.remove("REDIS_CACHE",Collections.singletonList(request.getOutOrderId()));
        OpLogModel.OpLogModelBuilder<String> builder = OpLogModel.builder();
        OpLogModel<String> opLogModel = builder.build();
        opLogModel.setModuleName(ModuleEnum.SALES.getModuleName());
        opLogModel.setModuleId(String.valueOf(ModuleEnum.SALES.getModuleId()));
        opLogModel.setObjectId(orderSDO.getId());
        opLogModel.setObjectName("id");
        opLogModel.setOperateType(OperateType.EDIT.getOperateType());
        opLogModel.setOperatorType(OperatorType.USER.getOperatorType());
        opLogModel.setOldValue(JSONObject.toJSONString(oldOrderSDO));
        Map<String, String> map = new HashMap<>();
        if (Objects.nonNull(employeeGetCurrentLoginResponse)){
            map.put("name", employeeGetCurrentLoginResponse.getEmployeeName());
        }
        map.put("active", OrderOperateType.EDIT.getDesc());
        String logInfo = JSONObject.toJSONString(map);
        opLogModel.setFeatures(logInfo);
        opLogModel.setNewValue(JSONObject.toJSONString(queryOrderSDO(orderSDO.getId())));
        log.asyncMonitorObjectChangeV2(opLogModel);
        return fag;*/
    }

    public Result<Boolean> modifySaleOrderV2(ModifyOrderRequest request) {
        log.info("ModifyOrderRequest request :modifySaleOrder方法" + JSONObject.toJSONString(request));
//        Date createDateTime = DateUtils.string2Date(request.getCreateDate());
//        Date pauseTime = DateUtils.string2Date("2021-12-29 00:00:00");
//        if (createDateTime != null && createDateTime.before(pauseTime)){
//            log.info("1229割接日期前的数据:" + request.getOutOrderId());
//            return Result.success(true);
//        }
        //获取当前登录人信息
        EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse = bcOtsService.employeeGetCurrentLogin();
        OrderQueryRequest queryRequest = new OrderQueryRequest();
        //sap同步015
        if (StringUtils.isNotBlank(request.getOutOrderId())) {
            String lockKey = "sapSync:" + request.getOutOrderId();
            try (SaleRedisLock lock = new SaleRedisLock("REDIS_CACHE", lockKey, 5 * 60 * 1000, 10 * 60 * 1000, 2000)) {
                if (!lock.lock()) {
                    log.error("modifySaleOrderV2未获取到锁|外部单号为:" + lockKey);
                    log.error("modifySaleOrderV2$015_fail");
                    throw new FunctionException("OTS-04-001-00-15-038");
                }
                log.info("ThreadId:"+Thread.currentThread().getId()+"|SaleRedis.key="+lockKey+"|lock");
                PageResult<List<OrderPageQueryResponse>> listPageResult = null;
                if (StringUtils.isNotBlank(request.getTradeOrderId())) {
                    OrderPageQueryRequest pageQueryRequest = new OrderPageQueryRequest();
                    pageQueryRequest.setId(request.getTradeOrderId());
                    listPageResult = orderQueryServiceRepository.pageQuery(pageQueryRequest);
                }

                if (listPageResult == null || CollectionUtils.isEmpty(listPageResult.getContent())) {
                    OrderPageQueryRequest innerQuery = new OrderPageQueryRequest();
                    innerQuery.setOuterOrderId(request.getOutOrderId());
                    listPageResult = orderQueryServiceRepository.pageQuery(innerQuery);
                }
                //查询不到就创建
                if (CollectionUtils.isEmpty(listPageResult.getContent())) {
                    OrderSDO orderSDO = new OrderSDO();
                    Date date = new Date();
                    //构建订单
                    extracted(request, orderSDO, "create");
                    orderSDO.setCreatorName(request.getCreator());
                    orderSDO.setGmtCreate(date);
                    orderSDO.setSyncVersion(0);
                    if (SaleOrderTag.LOGISTIC_RETURN_ORDER.getCode().equals(orderSDO.getOrderType())
                            || SaleOrderTag.STD_RETURN_ORDER.getCode().equals(orderSDO.getOrderType())
                            || SaleOrderTag.DS_STD_RETURN_ORDER.getCode().equals(orderSDO.getOrderType())
                            || SaleOrderTag.FREE_RETURN_ORDER.getCode().equals(orderSDO.getOrderType())) {
                        orderSDO.setStatus(OrderStatus.WAIT_RECEIVING.getCode());
                    } else if (SaleOrderTag.EXCHANGE_ORDER.getCode().equals(orderSDO.getOrderType())) {
                        orderSDO.setStatus(OrderStatus.WAIT_HANDLE.getCode());
                    } else {
                        orderSDO.setStatus(OrderStatus.BEFORE_DELIVERY.getCode());
                    }
                    SetOrderTag.getOrderTag(orderSDO.getOrderType(), orderSDO);
                    orderSDO.getOrderLineSDOS().forEach(orderLineSDO -> {
                        orderLineSDO.setStatus(orderSDO.getStatus());
                        if (StringUtils.isEmpty(orderLineSDO.getOrderLineTag())){
                            orderLineSDO.setOrderLineTag(orderSDO.getOrderTag());
                        }
                        orderLineSDO.setGmtCreate(date);
                    });
                    OrderWriteEntity orderWriteEntity = OrderWriteFactory.saveOrderZRE3(orderSDO);
                    List<BatchCreateOrderResponse> batchCreateOrderResponses = orderWriteEntity.batchSave();
                    for (BatchCreateOrderResponse response : batchCreateOrderResponses) {
                        OpLogModel.OpLogModelBuilder<String> builder = OpLogModel.builder();
                        OpLogModel<String> opLogModel = builder.build();
                        opLogModel.setModuleName(ModuleEnum.SALES.getModuleName());
                        opLogModel.setModuleId(String.valueOf(ModuleEnum.SALES.getModuleId()));
                        opLogModel.setObjectId(response.getOrderId());
                        opLogModel.setObjectName("orderId");
                        opLogModel.setOperateType(OperateType.EDIT.getOperateType());
                        opLogModel.setOperatorType(OperatorType.USER.getOperatorType());
                        Map<String, String> map = new HashMap<>();
                        if (Objects.nonNull(employeeGetCurrentLoginResponse)) {
                            map.put("name", employeeGetCurrentLoginResponse.getEmployeeName());
                        }
                        map.put("active", OrderOperateType.EDIT.getDesc());
                        String logInfo = JSONObject.toJSONString(map);
                        opLogModel.setFeatures(logInfo);
                        log.asyncMonitorObjectChangeV2(opLogModel);
                    }
                    return Result.success(true);
                }
                queryRequest.setId(listPageResult.getContent().get(0).getId());
                OrderQueryResponse query = orderQueryServiceRepository.query(queryRequest);
                return updateSaleOrderInfo(query, request, employeeGetCurrentLoginResponse);
            } catch (Exception e) {
                log.error("modifySaleOrderV2数据异常:", e);
                throw e;
            }
        } // 页面修改无销售单id、无需加锁
        else {
            if (null == request.getBaseInfo() || StringUtils.isBlank(request.getBaseInfo().getId())) {
                return Result.fail("OTS-05-001-10-16-031", "页面入参不能为空");
            }
            queryRequest.setId(request.getBaseInfo().getId());
            OrderQueryResponse query = orderQueryServiceRepository.query(queryRequest);
            return updateSaleOrderInfo(query, request, employeeGetCurrentLoginResponse);
        }
    }

    public Result<Boolean> updateSaleOrderInfo(OrderQueryResponse query, ModifyOrderRequest request, EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse) {
        OrderSDO orderSDO = SaveOrderConverter.respConverterSDO(query);
        // 旧数据
        OrderSDO oldOrderSDO = SaveOrderConverter.respConverterSDO(query);

        if (request.getBaseInfo() != null) {
            //页面参数转换
            extracted1(request, orderSDO);
        } else {
            //015参数转换
            extracted(request, orderSDO, "update");
            orderSDO.setModifierName(request.getCreator());
        }
        OrderWriteEntity orderWriteEntity = OrderWriteFactory.updateOrder(orderSDO);
        Result<Boolean> fag = orderWriteEntity.modify();
        //识别拒绝的子单并发送拒绝消息
        this.getRefusedId(oldOrderSDO, orderSDO);
        OpLogModel.OpLogModelBuilder<String> builder = OpLogModel.builder();
        OpLogModel<String> opLogModel = builder.build();
        opLogModel.setModuleName(ModuleEnum.SALES.getModuleName());
        opLogModel.setModuleId(String.valueOf(ModuleEnum.SALES.getModuleId()));
        opLogModel.setObjectId(orderSDO.getId());
        opLogModel.setObjectName("id");
        opLogModel.setOperateType(OperateType.EDIT.getOperateType());
        opLogModel.setOperatorType(OperatorType.USER.getOperatorType());
        opLogModel.setOldValue(JSONObject.toJSONString(oldOrderSDO));
        Map<String, String> map = new HashMap<>();
        if (Objects.nonNull(employeeGetCurrentLoginResponse)) {
            map.put("name", employeeGetCurrentLoginResponse.getEmployeeName());
        }
        map.put("active", OrderOperateType.EDIT.getDesc());
        String logInfo = JSONObject.toJSONString(map);
        opLogModel.setFeatures(logInfo);
        opLogModel.setNewValue(JSONObject.toJSONString(queryOrderSDO(orderSDO.getId())));
        log.asyncMonitorObjectChangeV2(opLogModel);
        return fag;
    }

    /**
     * 获取修改前后，新拒绝的子单有哪些
     *
     * @param oldOrderSDO
     * @param orderSDO
     * @return
     */
    private List<String> getRefusedId(OrderSDO oldOrderSDO, OrderSDO orderSDO) {
        List<OrderLineSDO> oldOrderLines = oldOrderSDO.getOrderLineSDOS();
        List<OrderLineSDO> newOrderLines = orderSDO.getOrderLineSDOS();
        if (CollectionUtils.isEmpty(oldOrderLines)) {
            return null;
        }
        Map<String, String> oldMap = oldOrderLines.stream().filter(orderLineSDO -> StringUtils.isNotBlank(orderLineSDO.getRefuseReasonCode())).collect(Collectors.toMap(OrderLineSDO::getId, OrderLineSDO::getRefuseReasonCode));

//        Map<String,String> newMap = newOrderLines.stream().filter(orderLineSDO -> StringUtils.isNotBlank(orderLineSDO.getRefuseReasonCode())).collect(Collectors.toMap(OrderLineSDO::getId,OrderLineSDO::getRefuseReasonCode));

        List<String> newRefuseIds = newOrderLines.stream().filter(orderLineSDO -> (StringUtils.isNotBlank(orderLineSDO.getRefuseReasonCode()) && !oldMap.containsKey(orderLineSDO.getId()))).map(OrderLineSDO::getId).collect(Collectors.toList());

        if (CollectionUtils.isNotEmpty(newRefuseIds)) {
            TradeMessageSDO tradeMessageSDO = new TradeMessageSDO();
            tradeMessageSDO.setOrderSDO(orderSDO);
            tradeMessageSDO.setAffectLineIds(newRefuseIds);
            String message = JSON.toJSONString(tradeMessageSDO);
            Map<String, String> map = new HashMap<>();
            map.put("_CZ_KEY", BcOtsConstants.TENANT_ID());
            log.info("orderId = " + orderSDO.getId() + ", message = " + message + ",map = " + JSON.toJSONString(map) + " start");
            messageService.sendMessage("sale_order_message", "CR_SALEORDER", "SaleRefused", orderSDO.getOrderBizId(), message, map);
        }
        return newRefuseIds;

    }

    private void extracted1(ModifyOrderRequest request, OrderSDO orderSDO) {
        SaveSaleOrderRequest baseInfo = request.getBaseInfo();
        //获取当前登录人
        EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse = bcOtsService.employeeGetCurrentLogin();
        if (StringUtils.isNotBlank(employeeGetCurrentLoginResponse.getEmployeeId()) && StringUtils.isNotBlank(employeeGetCurrentLoginResponse.getEmployeeName())) {
            orderSDO.setModifierId(employeeGetCurrentLoginResponse.getEmployeeId());
            orderSDO.setModifierName(employeeGetCurrentLoginResponse.getEmployeeName());
        }
        orderSDO.setId(baseInfo.getId());
        orderSDO.setOrderType(baseInfo.getOrderType());
        orderSDO.setOrderTypeName(baseInfo.getOrderTypeName());
        orderSDO.setReceiveAddressCode(baseInfo.getDeliveryAddr());
        orderSDO.setCustomerAccounts(baseInfo.getCustomerAccounts());
        orderSDO.setCustomerCode(baseInfo.getCustomerCode());
        orderSDO.setCustomerName(baseInfo.getCustomerName());
        orderSDO.setWareHouseCode(baseInfo.getShippingWarehouse());
        orderSDO.setOrganizationCode(baseInfo.getSalesOrganization());
        orderSDO.setChannelCode(baseInfo.getBuzChannel());
        orderSDO.setChannelName(baseInfo.getBuzChannelName());
        orderSDO.setSaleChannelCode(baseInfo.getSaleChannel());
        orderSDO.setSaleChannelName(baseInfo.getSaleChannelName());
        orderSDO.setDepartmentCode(baseInfo.getSaleDepartment());
        orderSDO.setDepartmentName(baseInfo.getSaleDepartmentName());
        orderSDO.setCustomerName(baseInfo.getCustomerName());
        orderSDO.setOrganizationName(baseInfo.getSalesOrganizationName());
        PaymentInformationSDO paymentInformationSDO = new PaymentInformationSDO();
//        if (StringUtils.isNotBlank(baseInfo.getCustomerAccounts())) {
//            paymentInformationSDO.setOrderTotalFee(Long.parseLong(baseInfo.getCustomerAccounts()));
//        }
        orderSDO.setCostCenter(baseInfo.getCostCenter());
        orderSDO.setCashCustomerName(baseInfo.getCashCustomerName());
        orderSDO.setCustomerReferenceNumber(baseInfo.getCustomerRefNo());
        orderSDO.setRemark(baseInfo.getRemark());
        orderSDO.setProductGroupCode(baseInfo.getGoodsGroup());
        orderSDO.setProductGroupName(baseInfo.getGoodsGroupName());
        //todo 单据日期
        if (StringUtils.isNotBlank(baseInfo.getUpdateTime())) {
            orderSDO.setGmtModified(DateFormatUtil.parseSimpleDateFormat(baseInfo.getUpdateTime()));
        }
        orderSDO.setCreateReason(baseInfo.getOrderReason());
        orderSDO.setCreatorId(baseInfo.getCreatorId());
        orderSDO.setCreatorName(baseInfo.getCreator());
        if (StringUtils.isNotBlank(baseInfo.getCustomerRefDate())) {
            SimpleDateFormat spf = new SimpleDateFormat("yyyy-MM-dd");
            Date date = null;
            try {
                date = spf.parse(baseInfo.getCustomerRefDate());
            } catch (ParseException e) {
                e.printStackTrace();
            }
            orderSDO.setCustomerExpectDate(date);
        }
        orderSDO.setContactor(baseInfo.getContactor());
        orderSDO.setContactorPhone(baseInfo.getPhone());
        orderSDO.setTransportModeCode(baseInfo.getDeliveryMethod());

        Map<String, OrderLineSDO> orderLineSDOMap = null;
        if (CollectionUtils.isNotEmpty(orderSDO.getOrderLineSDOS())) {
            orderLineSDOMap = orderSDO.getOrderLineSDOS().stream().collect(Collectors.toMap(OrderLineSDO::getId, o -> o));
        }
        Map<String, OrderLineSDO> finalOrderLineSDOMap = orderLineSDOMap;
        List<OrderLineSDO> orderLineSDOS = request.getOrderDetailList().stream().map(orderDetail -> {
            OrderLineSDO orderLineSDO = new OrderLineSDO();
            if (orderDetail.getId() != null) {
                orderLineSDO = finalOrderLineSDOMap.get(orderDetail.getId());
            }
            orderLineSDO.setId(orderDetail.getId());
            ScItemSDO scItemSDO = new ScItemSDO();
            scItemSDO.setScItemId(orderDetail.getGoodsId());
            scItemSDO.setScItemTitle(orderDetail.getGoodsName());
            scItemSDO.setUnitPrice(orderDetail.getUnitPrice() == null ? null : orderDetail.getUnitPrice());
            scItemSDO.setScItemOutCode(orderDetail.getGoodsCode());
            scItemSDO.setCategoryCode(orderDetail.getCategoryCode());
            scItemSDO.setCategoryDesc(orderDetail.getCategoryDesc());
            scItemSDO.setCategoryChildCode(orderDetail.getCategoryChildCode());
            scItemSDO.setCategoryChildDesc(orderDetail.getCategoryChildDesc());
            if (StringUtils.isNotBlank(orderDetail.getQuantity()) && null != scItemSDO.getUnitPrice()) {
                scItemSDO.setQuantity(Integer.parseInt(orderDetail.getQuantity()));
                orderLineSDO.setShouldPayFee(scItemSDO.getUnitPrice() * scItemSDO.getQuantity());
            }

            scItemSDO.setSaleUnit(orderDetail.getSaleUnit());
            scItemSDO.setSaleUnitName(orderDetail.getSaleUnitName());
            orderLineSDO.setRemark(orderDetail.getRemark());
            orderLineSDO.setOrderLineTag(orderDetail.getOrderLineTag());
            scItemSDO.setInventoryUnitCode(orderDetail.getInventoryUnitCode());
            scItemSDO.setInventoryUnitName(orderDetail.getInventoryUnit());
            if (StringUtils.isNotBlank(employeeGetCurrentLoginResponse.getEmployeeId()) && StringUtils.isNotBlank(employeeGetCurrentLoginResponse.getEmployeeName())) {
                orderLineSDO.setModifierId(employeeGetCurrentLoginResponse.getEmployeeId());
                orderLineSDO.setModifierName(employeeGetCurrentLoginResponse.getEmployeeName());
            }
            if (null != orderDetail.getUnitConvert()) {
                scItemSDO.setUnitConvert(String.valueOf(orderDetail.getUnitConvert()));
            }
            if ("return".equals(orderLineSDO.getOrderLineTag())) {
                orderLineSDO.setReturnCharacter("1");
            }
            orderLineSDO.setScItemSDO(scItemSDO);
            orderLineSDO.setRefuseReasonCode(orderDetail.getRejectReason());
            orderLineSDO.setCumulativeProcessingQuantity(orderDetail.getCumulativeProcessingQuantity());
            orderLineSDO.setCumulativeReceiptQuantity(orderDetail.getCumulativeReceiptQuantity());
            orderLineSDO.setSerialNumber(orderDetail.getLineNum());
            if (StringUtils.isNotBlank(orderDetail.getQuantity()) && StringUtils.isNotBlank(orderDetail.getUnitConvert())) {
                BigDecimal quantity = new BigDecimal(orderDetail.getQuantity());
                BigDecimal unitConvert = new BigDecimal(orderDetail.getUnitConvert());
                BigDecimal basicUnitQty = quantity.divide(unitConvert,3, BigDecimal.ROUND_DOWN);
                if (MapUtils.isEmpty(orderLineSDO.getFeatures())) {
                    Map<String, String> features = new HashMap<>();
                    features.put(SaleOrderConstants.BASIC_UNIT_QTY, basicUnitQty.toString());
                    //手工单价
                    features.put(SaleOrderConstants.MANUAL_PRICE, orderDetail.getManualPrice());
                    //手工总金额
                    features.put(SaleOrderConstants.MANUAL_TOTAL_AMOUNT, orderDetail.getManualTotalAmount());
                    orderLineSDO.setFeatures(features);
                } else {
                    orderLineSDO.getFeatures().put(SaleOrderConstants.BASIC_UNIT_QTY, basicUnitQty.toString());
                    //手工单价
                    orderLineSDO.getFeatures().put(SaleOrderConstants.MANUAL_PRICE, orderDetail.getManualPrice());
                    //手工总金额
                    orderLineSDO.getFeatures().put(SaleOrderConstants.MANUAL_TOTAL_AMOUNT, orderDetail.getManualTotalAmount());

                }
            }
            orderLineSDO.setGmtModified(new Date());
            return orderLineSDO;
        }).collect(Collectors.toList());
        orderSDO.setOrderLineSDOS(orderLineSDOS);
        orderSDO.setGmtModified(new Date());
    }

    @Override
    @FacadeInvoker
    public Result<Boolean> cancelOrder(UpdateOrderRequest request) {
        //获取当前登录人信息
        EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse = bcOtsService.employeeGetCurrentLogin();
        OrderQueryRequest orderQueryRequest = new OrderQueryRequest();
        orderQueryRequest.setId(request.getId());
        OrderQueryResponse query = orderQueryServiceRepository.query(orderQueryRequest);
        OrderSDO orderSDO = SaveOrderConverter.respConverterSDO(query);
        OrderWriteEntity orderWriteEntity = OrderWriteFactory.updateOrder(orderSDO);
        Result<Boolean> fag = orderWriteEntity.cancelOrder();

        OpLogModel.OpLogModelBuilder<String> builder = OpLogModel.builder();
        OpLogModel<String> opLogModel = builder.build();
        opLogModel.setModuleName(ModuleEnum.SALES.getModuleName());
        opLogModel.setModuleId(String.valueOf(ModuleEnum.SALES.getModuleId()));
        opLogModel.setObjectId(orderSDO.getId());
        opLogModel.setObjectName("id");
        opLogModel.setOperateType(OperateType.EDIT.getOperateType());
        Map<String, String> map = new HashMap<>();
        if (Objects.nonNull(employeeGetCurrentLoginResponse)) {
            map.put("name", employeeGetCurrentLoginResponse.getEmployeeName());
        }
        map.put("active", OrderOperateType.CANCEL.getDesc());
        String logInfo = JSONObject.toJSONString(map);
        opLogModel.setFeatures(logInfo);
        opLogModel.setOperatorType(OperatorType.USER.getOperatorType());
        log.asyncMonitorObjectChangeV2(opLogModel);
        return fag;
    }

    @Override
    @FacadeInvoker
    public Result<Boolean> submitSaleOrder(UpdateOrderRequest request) {

        //获取当前登录人信息
        try (RedisLock lock = new RedisLock("REDIS_CACHE", "submitSaleOrder:" + request.getId(), 0, 8 * 1000)) {
            if (!lock.lock()) {
                return Result.fail(false, "OTS-04-001-00-15-040", request.getId() + "提交处理中，请勿重复提交！");
            }
            EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse = bcOtsService.employeeGetCurrentLogin();
            OrderQueryRequest orderQueryRequest = new OrderQueryRequest();
            orderQueryRequest.setId(request.getId());
            OrderQueryResponse query = orderQueryServiceRepository.query(orderQueryRequest);

            if (StringUtils.isBlank(query.getOrderStatus()) || !(query.getOrderStatus().equals(String.valueOf(OrderStatus.BEFORE_SUBMIT.getCode())) || query.getOrderStatus().equals(String.valueOf(OrderStatus.STAY_PUSH.getCode())))) {
                return Result.fail(false, "OTS-04-001-00-15-041", "当前订单状态已变更,请刷新页面后重试！");
            }

            if (CollectionUtils.isEmpty(query.getOrderDetailList())) {
                return Result.fail("999", "没有子单不允许提交");
            }

            //校验仓库是否禁用
            QueryWarehouseByIdRequest byIdRequest = new QueryWarehouseByIdRequest();
            byIdRequest.setId(query.getShippingWarehouse());
            Result<WarehouseInfo> warehouseInfoResult = unifiedInventoryService.queryWarehouseById(byIdRequest);
            if (warehouseInfoResult == null || warehouseInfoResult.getResult() == null || warehouseInfoResult.getResult().getStatus() == null) {
                return Result.fail("888", "未查询对应的仓库");
            }
            if (warehouseInfoResult.getResult().getStatus() == 2) {
                return Result.fail("999", "此仓库禁用,不允许提交");
            }

            for (OrderDetailDTO orderDetailDTO : query.getOrderDetailList()) {
                // 校验商品是否 可用
                Boolean aBoolean = checkScItemStatus(orderDetailDTO.getGoodsCode());
                if (aBoolean != null) {
                    if (!aBoolean) {
                        return Result.fail(null, "货品状态异常");
                    }
                } else {
                    return Result.fail(null, "货品状态异常");
                }
                if (StringUtils.isEmpty(orderDetailDTO.getUnitPrice())) {
                    return Result.fail("888", "货品价格为空不允许提交");
                }
                if (!orderDetailDTO.getUnitPrice().matches("^[+]?([0-9]+\\.?)?[0-9]+$")) {
                    return Result.fail("888", "货品价格为负数不允许提交");
                }
            }
            OrderSDO orderSDO = SaveOrderConverter.respConverterSDO(query);
            OrderWriteEntity orderWriteEntity = OrderWriteFactory.updateOrder(orderSDO);
            Result<Boolean> fag = orderWriteEntity.submit();

            OpLogModel.OpLogModelBuilder<String> builder = OpLogModel.builder();
            OpLogModel<String> opLogModel = builder.build();
            opLogModel.setModuleName(ModuleEnum.SALES.getModuleName());
            opLogModel.setModuleId(String.valueOf(ModuleEnum.SALES.getModuleId()));
            opLogModel.setObjectId(orderSDO.getId());
            opLogModel.setObjectName("id");
            opLogModel.setOperateType(OperateType.EDIT.getOperateType());
            opLogModel.setOperatorType(OperatorType.USER.getOperatorType());
            opLogModel.setOldValue(JSONObject.toJSONString(orderSDO));
            Map<String, String> map = new HashMap<>();
            if (Objects.nonNull(employeeGetCurrentLoginResponse)) {
                map.put("name", employeeGetCurrentLoginResponse.getEmployeeName());
            }
            map.put("active", OrderOperateType.SUBMIT.getDesc());
            String logInfo = JSONObject.toJSONString(map);
            opLogModel.setFeatures(logInfo);
            opLogModel.setNewValue(JSONObject.toJSONString(queryOrderSDO(orderSDO.getId())));
            log.asyncMonitorObjectChangeV2(opLogModel);
            return fag;
        } catch (Exception e) {
            log.error("销售订单提交异常:", e);
            return Result.fail(false, "OTS-04-001-00-15-042", "销售订单:" + request.getId() + ",提交异常:" + e.getMessage());
        }
    }

    @Override
    public Result<Boolean> sapCallBack(ModifyOrderRequest request) {
        return sapCallBackV2(request);
        //request去除单引号字符 因为纪元无法识别单引号，导致报错
        /*if (StringUtils.isNotBlank(request.getMessage())){
            request.setMessage(request.getMessage().replace("'",""));
        }
        //获取当前登录人信息
//        EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse = bcOtsService.employeeGetCurrentLogin();
        OrderQueryRequest queryRequest = new OrderQueryRequest();
        queryRequest.setId(request.getInnerKey());
        OrderQueryResponse query = orderQueryServiceRepository.query(queryRequest);
        if (StringUtils.isNotBlank(query.getOrderStatus()) && OrderStatus.BEFORE_DELIVERY.getCode().equals(Integer.parseInt(query.getOrderStatus()))) {
            return Result.success(true);
        }
        OrderSDO orderSDO = SaveOrderConverter.respConverterSDO(query);
        //成功
        if (request.getSuccess()) {
            orderSDO.setOuterOrderId(request.getOuterKey());
            if (orderSDO.getOrderTag().equals("return")) {
                orderSDO.setStatus(OrderStatus.WAIT_RECEIVING.getCode());
            } else if (orderSDO.getOrderTag().equals("exchange")) {
                orderSDO.setStatus(OrderStatus.WAIT_HANDLE.getCode());
                if (CollectionUtils.isNotEmpty(orderSDO.getOrderLineSDOS())) {
                    orderSDO.getOrderLineSDOS().forEach(SetOrderTag::setExchangeOrderLineSDOStatus);
                }
            } else {
                orderSDO.setStatus(OrderStatus.BEFORE_DELIVERY.getCode());
                if (CollectionUtils.isNotEmpty(orderSDO.getOrderLineSDOS())) {
                    for (OrderLineSDO orderLineSDO : orderSDO.getOrderLineSDOS()) {
                        orderLineSDO.setStatus(OrderStatus.BEFORE_DELIVERY.getCode());
                    }
                }
            }

            if (MapUtils.isNotEmpty(orderSDO.getFeatures())) {
                orderSDO.getFeatures().put(SaleOrderConstants.EXT_MESSAGE, request.getMessage());
            } else {
                Map<String, String> map = new HashMap<>();
                map.put(SaleOrderConstants.EXT_MESSAGE, request.getMessage());
                orderSDO.setFeatures(map);
            }
        } else { //失败
            orderSDO.setStatus(OrderStatus.STAY_PUSH.getCode());
            if (MapUtils.isNotEmpty(orderSDO.getFeatures())) {
                orderSDO.getFeatures().put(SaleOrderConstants.EXT_MESSAGE, request.getMessage());
            } else {
                Map<String, String> map = new HashMap<>();
                map.put(SaleOrderConstants.EXT_MESSAGE, request.getMessage());
                orderSDO.setFeatures(map);
            }
        }
        OrderWriteEntity orderWriteEntity = OrderWriteFactory.updateOrder(orderSDO);
        Result<Boolean> fag = orderWriteEntity.modify();

        OpLogModel.OpLogModelBuilder<String> builder = OpLogModel.builder();
        OpLogModel<String> opLogModel = builder.build();
        opLogModel.setModuleName(ModuleEnum.SALES.getModuleName());
        opLogModel.setModuleId(String.valueOf(ModuleEnum.SALES.getModuleId()));
        opLogModel.setObjectId(orderSDO.getId());
        opLogModel.setObjectName("id");
        opLogModel.setOperateType(OperateType.EDIT.getOperateType());
        opLogModel.setOperatorType(OperatorType.USER.getOperatorType());
        Map<String, String> map = new HashMap<>();
        map.put("name", "系统");
        map.put("active", OrderOperateType.EDIT.getDesc());
        String logInfo = JSONObject.toJSONString(map);
        opLogModel.setFeatures(logInfo);
        log.asyncMonitorObjectChangeV2(opLogModel);
        return fag;*/
    }

    public Result<Boolean> sapCallBackV2(ModifyOrderRequest request) {
        log.info("sapCallBackV2:" + JSON.toJSONString(request));
        //request去除单引号字符 因为纪元无法识别单引号，导致报错
        if (StringUtils.isNotBlank(request.getMessage())) {
            request.setMessage(request.getMessage().replace("'", ""));
        }
        String lockBackKey = "sapBackSync:" + request.getInnerKey();
        try (SaleRedisLock lockBack = new SaleRedisLock("REDIS_CACHE", lockBackKey, 2 * 60 * 1000, 5 * 60 * 1000, 2000)) {
            log.info("sapCallBackV2入口 加锁 " + lockBackKey + "|时间：" + new Date());
            if (!lockBack.lock()) {
                log.error("sapCallBackV2入口 锁超时RedisLock获取锁失败:" + lockBackKey);
                log.error("sapCallBackV2$006_fail");
                //
            }
            if (request.getSuccess()) {
                // sap同步成功、外部单号不能为空
                if (StringUtils.isBlank(request.getOuterKey())) {
                    throw new FunctionException("OTS-05-001-10-16-028");
                }
                String lockKey = "sapSync:" + request.getOuterKey();
                try (SaleRedisLock lock = new SaleRedisLock("REDIS_CACHE", lockKey, 5 * 60 * 1000, 10 * 60 * 1000, 2000)) {
                    log.info("sapCallBackV2 加锁 " + lockKey + "|时间：" + new Date());
                    if (!lock.lock()) {
                        log.error("sapCallBackV2 RedisLock获取锁失败:" + lockKey);
                        log.error("sapCallBackV2$006_fail");
                        throw new FunctionException("OTS-04-001-00-15-038");
                    }
                    log.info("ThreadId:" + Thread.currentThread().getId() + "|SaleRedis.key=" + lockKey + "|lock");
                    OrderQueryRequest queryRequest = new OrderQueryRequest();
                    queryRequest.setId(request.getInnerKey());
                    OrderQueryResponse query = orderQueryServiceRepository.query(queryRequest);
                    if (StringUtils.isNotBlank(query.getOrderStatus())) {
                        // 非已推送或待推送状态的销售单不允许推进为待交货
                        if (!checkOrderStatus(Integer.parseInt(query.getOrderStatus()))) {
                            log.info("sapCallBackV2|当前订单:" + request.getInnerKey() + "|状态:" + query.getOrderStatus() + "|不允许推进");
                            return Result.success(true);
                        }
                    }
                    OrderSDO orderSDO = SaveOrderConverter.respConverterSDO(query);
                    orderSDO.setOuterOrderId(request.getOuterKey());
                    if (orderSDO.getOrderTag().equals("return")) {
                        orderSDO.setStatus(OrderStatus.WAIT_RECEIVING.getCode());
                    } else if (orderSDO.getOrderTag().equals("exchange")) {
                        orderSDO.setStatus(OrderStatus.WAIT_HANDLE.getCode());
                        if (CollectionUtils.isNotEmpty(orderSDO.getOrderLineSDOS())) {
                            orderSDO.getOrderLineSDOS().forEach(SetOrderTag::setExchangeOrderLineSDOStatus);
                        }
                    } else {
                        orderSDO.setStatus(OrderStatus.BEFORE_DELIVERY.getCode());
                        if (CollectionUtils.isNotEmpty(orderSDO.getOrderLineSDOS())) {
                            for (OrderLineSDO orderLineSDO : orderSDO.getOrderLineSDOS()) {
                                orderLineSDO.setStatus(OrderStatus.BEFORE_DELIVERY.getCode());
                            }
                        }
                    }

                    if (MapUtils.isNotEmpty(orderSDO.getFeatures())) {
                        orderSDO.getFeatures().put(SaleOrderConstants.EXT_MESSAGE, request.getMessage());
                    } else {
                        Map<String, String> map = new HashMap<>();
                        map.put(SaleOrderConstants.EXT_MESSAGE, request.getMessage());
                        orderSDO.setFeatures(map);
                    }
                    Result<Boolean> modifyResult=updateSapSyncSaleOrderStatus(orderSDO);
                    //20230421新增的推送消息 系统推送订单给NYK
                    return modifyResult;
                } catch (Exception e) {
                    log.error("OrderServiceImpl.sapCallBackNew|sap回调异常:", e);
                    throw e;
                }
            } else {
                OrderQueryRequest queryRequest = new OrderQueryRequest();
                queryRequest.setId(request.getInnerKey());
                OrderQueryResponse query = orderQueryServiceRepository.query(queryRequest);

                if (StringUtils.isNotBlank(query.getOrderStatus())) {
                    if (!OrderStatus.PUSHING.getCode().equals(Integer.parseInt(query.getOrderStatus()))) {
                        return Result.success(true);
                    }
                }
                OrderSDO orderSDO = SaveOrderConverter.respConverterSDO(query);
                // sap回调时,若同步sap状态失败,将销售单状态置为待推送,并记录错误信息
                //外部单号不为空 考虑重复提交，sap返回了false，订单重复创建说明
                if (StringUtils.isBlank(orderSDO.getOuterOrderId())) {
                    orderSDO.setStatus(OrderStatus.STAY_PUSH.getCode());
                    //子单状态也变更
                    for(OrderLineSDO x: orderSDO.getOrderLineSDOS()){
                        x.setStatus(OrderStatus.STAY_PUSH.getCode());
                    }
                } else {
                    return Result.success(true);
                }
                if (MapUtils.isNotEmpty(orderSDO.getFeatures())) {
                    String pushCount = orderSDO.getFeatures().get(SaleOrderConstants.PUSH_COUNT);
                    Integer count = pushCount == null ? 1 : Integer.parseInt(pushCount) + 1;
                    orderSDO.getFeatures().put(SaleOrderConstants.EXT_MESSAGE, request.getMessage());
                    orderSDO.getFeatures().put(SaleOrderConstants.PUSH_COUNT, String.valueOf(count));
                } else {
                    Map<String, String> map = new HashMap<>();
                    map.put(SaleOrderConstants.EXT_MESSAGE, request.getMessage());
                    map.put(SaleOrderConstants.PUSH_COUNT, "1");
                    orderSDO.setFeatures(map);
                }
                Result<Boolean> modifyResult=updateSapSyncSaleOrderStatus(orderSDO);
                return modifyResult;
            }
        } catch (Exception e) {
            log.error("OrderServiceImpl.sapCallBackV2|sap回调异常:", e);
            throw e;
        }
    }


    private boolean checkOrderStatus(int status) {
        if (OrderStatus.PUSHING.getCode().equals(status) || OrderStatus.STAY_PUSH.getCode().equals(status)
                || OrderStatus.BEFORE_DELIVERY.getCode().equals(status) || OrderStatus.WAIT_HANDLE.getCode().equals(status)
                || OrderStatus.WAIT_RECEIVING.getCode().equals(status)) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    private Result<Boolean> updateSapSyncSaleOrderStatus(OrderSDO orderSDO) {
        OrderWriteEntity orderWriteEntity = OrderWriteFactory.updateOrder(orderSDO);
        Result<Boolean> result = orderWriteEntity.modify();
        OpLogModel.OpLogModelBuilder<String> builder = OpLogModel.builder();
        OpLogModel<String> opLogModel = builder.build();
        opLogModel.setModuleName(ModuleEnum.SALES.getModuleName());
        opLogModel.setModuleId(String.valueOf(ModuleEnum.SALES.getModuleId()));
        opLogModel.setObjectId(orderSDO.getId());
        opLogModel.setObjectName("id");
        opLogModel.setOperateType(OperateType.EDIT.getOperateType());
        opLogModel.setOperatorType(OperatorType.USER.getOperatorType());
        Map<String, String> map = new HashMap<>();
        map.put("name", "系统");
        map.put("active", OrderOperateType.EDIT.getDesc());
        String logInfo = JSONObject.toJSONString(map);
        opLogModel.setFeatures(logInfo);
        log.asyncMonitorObjectChangeV2(opLogModel);
        return result;
    }

    private void extracted(ModifyOrderRequest request, OrderSDO orderSDO, String tag) {
        orderSDO.setOuterOrderId(request.getOutOrderId());
        SetOrderTag.getOrderTag(request.getOrderType(), orderSDO);
        //orderSDO.setOrderTag(SaleOrderTag.LOGISTIC_RETURN_ORDER.getCode().equals(request.getOrderType())?"return":"normal");
        orderSDO.setOrderType(request.getOrderType());
        orderSDO.setOrganizationCode(request.getSaleOrganizationCode());
        orderSDO.setOrganizationName(request.getSaleOrganizationName());
        orderSDO.setChannelCode(request.getSapChannel());
        orderSDO.setChannelName(request.getSapChannelName());
        orderSDO.setProductGroupCode(request.getProductGroupCode());
        orderSDO.setProductGroupName(request.getProductGroupName());
        orderSDO.setCreatorId(request.getCreator());
        orderSDO.setModifierId(request.getModifier());
        orderSDO.setSaleChannelCode(request.getSaleChannelCode());
        orderSDO.setSaleChannelName(request.getSaleChannelName());
        orderSDO.setBisUnitCode(request.getBisUnitCode());
        //更新时不做更新，只有创建时，才赋值
        if (orderSDO.getDepartmentCode() == null) {
            orderSDO.setDepartmentCode(request.getSaleDepartmentCode());
            orderSDO.setDepartmentName(request.getSaleDepartmentName());
        }
        //订单类型判断，无论是更新还是创建均进行识别
        String orderTag = SetOrderTag.getOrderTag(request.getOrderType());
        orderSDO.setOrderTag(orderTag);
        if ("update".equals(tag) && (OrderStatus.STAY_PUSH.getCode().equals(orderSDO.getStatus())
        || OrderStatus.PUSHING.getCode().equals(orderSDO.getStatus()))) {
            SetOrderTag.setOrderSDOStatusOne(orderSDO);
        }
        //设置features字段begin
        Map<String, String> features = orderSDO.getFeatures();
        if (MapUtils.isEmpty(features)) {
            features = new HashMap<>();
            orderSDO.setFeatures(features);
        }
        features.put(SaleOrderConstants.BEGIN_TIME, request.getBeginTime());
        features.put(SaleOrderConstants.PRICE_TIME, request.getPriceTime());
        //设置信贷检查情况
        this.setCreditCheck(features, request.getCreditCheckStatus());
        //设置features字段end

        orderSDO.setGmtModified(request.getGmtModified() == null ? null : DateFormatUtil.parseSimpleDateFormat(request.getGmtModified()));
        orderSDO.setCustomerExpectDate(request.getExpectedDeliveryTime() == null ? null : DateFormatUtil.parseSimpleDateFormat(request.getExpectedDeliveryTime()));
        orderSDO.setCustomerCode(request.getSoldPartCode());
        orderSDO.setCustomerName(request.getSoldPartName());
        orderSDO.setReceiveAddressCode(request.getDeliveryPartCode());
        orderSDO.setReceiveDetailAddress(request.getDeliveryPartName());
        orderSDO.setTransportModeCode(request.getShipType());
        orderSDO.setRemark(request.getRemark());
        orderSDO.setCustomerReferenceNumber(request.getCustomerReferenceNo());
        orderSDO.setCashCustomerName(request.getCashCustomerName());
        orderSDO.setCostCenter(request.getCostCenter());
        orderSDO.setCreateReason(request.getCreateReason());
        orderSDO.setCustomerAccounts(request.getCustomerAccounts());
        orderSDO.setContactor(request.getContactor());
        orderSDO.setContactorPhone(request.getContactorPhone());
        //key = 子单行号
        Map<String, OrderLineSDO> orderLineMap = Optional.ofNullable(orderSDO.getOrderLineSDOS()).orElse(Lists.newArrayList()).stream().collect(Collectors.toMap(OrderLineSDO::getSerialNumber, o -> o, (k1, k2) -> k1));
        //key = 外部子单行号
        Map<String, OrderLineSDO> outOrderLineMap = Optional.ofNullable(orderSDO.getOrderLineSDOS()).orElse(Lists.newArrayList()).stream().collect(Collectors.toMap(OrderLineSDO::getOuterOrderLineId, o -> o, (k1, k2) -> k1));

        if (CollectionUtils.isNotEmpty(request.getModifyOrderLineRequests())) {
            List<OrderLineSDO> orderLineSDOList = request.getModifyOrderLineRequests().stream().map(modifyOrderLineRequest -> {
                // 如果有已存在子单
                orderSDO.setWareHouseCode(modifyOrderLineRequest.getWarehouseCode());
                orderSDO.setWareHouseName(modifyOrderLineRequest.getWarehouseName());

                OrderLineSDO orderLineSDO = null;

                if (orderLineMap.containsKey(modifyOrderLineRequest.getOrderLineId())) {
                    orderLineSDO = orderLineMap.get(modifyOrderLineRequest.getOrderLineId());
                }
                if (orderLineSDO == null && outOrderLineMap.containsKey(modifyOrderLineRequest.getOutOrderLineId())) {
                    orderLineSDO = outOrderLineMap.get(modifyOrderLineRequest.getOutOrderLineId());
                }
                if (orderLineSDO == null) {
                    orderLineSDO = new OrderLineSDO();
                    orderLineSDO.setSerialNumber(modifyOrderLineRequest.getOrderLineId());
                }

                orderLineSDO.setOuterOrderLineId(modifyOrderLineRequest.getOutOrderLineId());
                ScItemSDO scItemSDO = new ScItemSDO();
                scItemSDO.setScItemId(modifyOrderLineRequest.getScItemId());
                scItemSDO.setScItemTitle(modifyOrderLineRequest.getScItemName());
                scItemSDO.setQuantity(Integer.valueOf(modifyOrderLineRequest.getQuantity()));
                scItemSDO.setActivityPrice(modifyOrderLineRequest.getActivityPrice() == null ? null : Long.valueOf(modifyOrderLineRequest.getActivityPrice()));
                scItemSDO.setUnitPrice(modifyOrderLineRequest.getPrice() == null ? null : Long.valueOf(modifyOrderLineRequest.getPrice()));
                scItemSDO.setScItemOutCode(modifyOrderLineRequest.getScItemOutCode());

                scItemSDO.setSaleUnit(modifyOrderLineRequest.getSaleUnit());
                scItemSDO.setSaleUnitName(modifyOrderLineRequest.getSaleUnitName());
                orderLineSDO.setShouldPayFee(modifyOrderLineRequest.getSubTotalAmount() == null ? null : Long.valueOf(modifyOrderLineRequest.getSubTotalAmount()));
                scItemSDO.setInventoryUnitName(modifyOrderLineRequest.getInventoryUnit());
                scItemSDO.setInventoryUnitCode(modifyOrderLineRequest.getInventoryUnitCode());
                scItemSDO.setUnitConvert(modifyOrderLineRequest.getUnitConvert());
                //2022-01-02
                scItemSDO.setCategoryCode(modifyOrderLineRequest.getCategoryCode());
                scItemSDO.setCategoryDesc(modifyOrderLineRequest.getCategoryDesc());
                scItemSDO.setCategoryChildCode(modifyOrderLineRequest.getCategoryChildCode());
                scItemSDO.setCategoryChildDesc(modifyOrderLineRequest.getCategoryChildDesc());

                orderLineSDO.setReturnCharacter(modifyOrderLineRequest.getReturnFlag());
                orderLineSDO.setRefuseReasonCode(modifyOrderLineRequest.getCloseCode());
                orderLineSDO.setRefuseReasonName(modifyOrderLineRequest.getCloseReason());
                orderLineSDO.setScItemSDO(scItemSDO);
                orderLineSDO.setGmtModified(new Date());
                //识别子单标签
                if (StringUtils.isNotBlank(orderTag)){
                    if (SetOrderTag.EXCHANGE.equals(orderTag)){
                        if ("1".equals(modifyOrderLineRequest.getReturnFlag())){
                            orderLineSDO.setOrderLineTag(SetOrderTag.RETURN);
                        }else {
                            orderLineSDO.setOrderLineTag(SetOrderTag.EXCHANGE);
                        }

                    }
                    if (SetOrderTag.RETURN.equals(orderTag)){
                        orderLineSDO.setOrderLineTag(SetOrderTag.RETURN);
                    }
                    if (SetOrderTag.NORMAL.equals(orderTag)){
                        orderLineSDO.setOrderLineTag(SetOrderTag.NORMAL);
                    }
                }
                if ("update".equals(tag) && (OrderStatus.STAY_PUSH.getCode().equals(orderLineSDO.getStatus())
                        || OrderStatus.PUSHING.getCode().equals(orderLineSDO.getStatus()))) {
                    SetOrderTag.setOrderLineSDOStatusOne(orderLineSDO);
                }

                //modify by 皓晖 at 20211217 for 优化扩展字段赋值 begin
                //设置orderLine扩展字段
                this.setOrderLineFeature(modifyOrderLineRequest, orderLineSDO);
                //modify by 皓晖 at 20211217 for 优化扩展字段赋值 end
                if ("create".equals(tag)) {
                    orderLineSDO.setActivityCode(modifyOrderLineRequest.getActivityCode());
                    orderLineSDO.getFeatures().put("activityDteails", modifyOrderLineRequest.getActivityFeature());
                }
                return orderLineSDO;
            }).collect(Collectors.toList());
            orderSDO.setOrderLineSDOS(orderLineSDOList);
            orderSDO.setGmtModified(new Date());
        }
    }

    private void setOrderLineFeature(ModifyOrderLineRequest modifyOrderLineRequest, OrderLineSDO orderLineSDO) {
        Map<String, String> orderLineMap = new HashMap<>();
        if (StringUtils.isNotBlank(modifyOrderLineRequest.getFeatures())) {
            orderLineMap = JSONObject.parseObject(modifyOrderLineRequest.getFeatures(), Map.class);
        }

        orderLineMap.put(SaleOrderConstants.GIFT_ACTIVITY_ID, modifyOrderLineRequest.getGiftActivityId());
        orderLineMap.put(SaleOrderConstants.GIFT_PROMOTION_ID, modifyOrderLineRequest.getGiftPromotionId());
        orderLineMap.put(SaleOrderConstants.GIFT_FLAG, modifyOrderLineRequest.getGiftFlag());
        orderLineMap.put(SaleOrderConstants.SPECIAL_ACTIVITY_ID, modifyOrderLineRequest.getSpecialActivityId());
        orderLineMap.put(SaleOrderConstants.SPECIAL_PROMOTION_ID, modifyOrderLineRequest.getSpecialPromotionId());
        orderLineMap.put(SaleOrderConstants.MANUAL_PROMOTION_ID, modifyOrderLineRequest.getManualPromotionId());
        orderLineMap.put(SaleOrderConstants.TURNING_PRICE, modifyOrderLineRequest.getTurningPrice());
        orderLineMap.put(SaleOrderConstants.DCT_BEFORE_PRICE, modifyOrderLineRequest.getDctBeforePrice());
        orderLineMap.put(SaleOrderConstants.DISCOUNT, modifyOrderLineRequest.getDiscount());
        orderLineMap.put(SaleOrderConstants.NK_PRICE, modifyOrderLineRequest.getNkPrice());
        orderLineMap.put(SaleOrderConstants.SHIP_POINT, modifyOrderLineRequest.getShipPoint());
        orderLineMap.put(SaleOrderConstants.INVENTORY_CODE, modifyOrderLineRequest.getInventoryCode());
        orderLineMap.put(SaleOrderConstants.FACTORY_CODE, modifyOrderLineRequest.getFactoryCode());
        orderLineMap.put(SaleOrderConstants.ACT_OCC_QTY, modifyOrderLineRequest.getActOccQty());
        orderLineMap.put(SaleOrderConstants.ACT_OCC_FEE, modifyOrderLineRequest.getActOccFee());

        Map<String,String> orderLineFeatures = orderLineSDO.getFeatures();
        if (orderLineFeatures != null) {
            orderLineFeatures.putAll(orderLineMap);
        }else {
            orderLineFeatures = orderLineMap;
        }
        orderLineSDO.setFeatures(orderLineFeatures);
    }

    @Override
    @EpochTransactional(appCode = "ots_b2b_trade_center", dataSourceCode = "cr_ots", dataSourceType = "app")
    public Result<Boolean> sapDeleteSaleOrder(SapDeleteSaleOrderRequest sapDeleteSaleOrderRequest) {
        log.info("OrderServiceImpl sapDeleteSaleOrder requestParams:" + JSONObject.toJSONString(sapDeleteSaleOrderRequest));
        OrderPageQueryRequest orderPageQueryRequest = new OrderPageQueryRequest();
        orderPageQueryRequest.setOuterOrderId(sapDeleteSaleOrderRequest.getOutOrderId());
        PageResult<List<OrderPageQueryResponse>> listPageResult = orderQueryServiceRepository.pageQuery(orderPageQueryRequest);
        if (listPageResult == null || CollectionUtils.isEmpty(listPageResult.getContent())) {
            AllocateOrderLoadListRequest allocateOrderLoadListRequest = new AllocateOrderLoadListRequest();
            allocateOrderLoadListRequest.setType(AllocateOrderTypeEnum.HEADQUARTER_SALES.getType());
            allocateOrderLoadListRequest.setOutAllocateOrderId(sapDeleteSaleOrderRequest.getOutOrderId());
            Result<List<AllocateOrder>> allocateOrderListPageResult = allocateOrderService.loadAllocateOrderList(allocateOrderLoadListRequest);
            log.info("关联查询调拨单 结果: {} ",JSONObject.toJSONString(allocateOrderListPageResult));
            //根据外部单号查询总部销售调拨单为空 报错
            if (allocateOrderListPageResult == null ||  CollectionUtils.isEmpty(allocateOrderListPageResult.getResult())) {
                log.error("未查询到订单，订单号：" + sapDeleteSaleOrderRequest.getOutOrderId());
                throw new FacadeException("OTS-05-001-10-16-050", sapDeleteSaleOrderRequest.getOutOrderId());
            } else {
                //查询总部销售调拨单子单 统计数量并删除子单
                AllocateOrder allocateOrder = allocateOrderListPageResult.getResult().get(0);
                Result<Boolean> booleanResult = deleteAllocateOrder(allocateOrder);
                if (!booleanResult.getResult()) {
                    log.error("关联删除总部销售调拨单失败 订单号：" + sapDeleteSaleOrderRequest.getOutOrderId());
                    throw new FacadeException("OTS-05-001-10-16-051", sapDeleteSaleOrderRequest.getOutOrderId());
                }
                return Result.success(true);
            }
        }
        OrderPageQueryResponse orderPageQueryResponse = listPageResult.getContent().get(0);
        if (SaleOrderTag.STD_RETURN_ORDER.getDesc().equals(orderPageQueryResponse.getOrderType())) {
            //退货订单 不是待收货状态就报错
            if (OrderStatus.COMPLETED.getCode().equals(Integer.parseInt(orderPageQueryResponse.getStatusCode()))
            || OrderStatus.PART_RECEIVING.getCode().equals(Integer.parseInt(orderPageQueryResponse.getStatusCode()))) {
                log.error("该退货订单不是待收货状态无法删除，订单号：" + sapDeleteSaleOrderRequest.getOutOrderId());
                throw new FacadeException("OTS-05-001-10-16-045", sapDeleteSaleOrderRequest.getOutOrderId());
            }
        } else if (SaleOrderTag.EXCHANGE_ORDER.getDesc().equals(orderPageQueryResponse.getOrderType())) {
            //换货订单 不是待处理状态就报错
            if (OrderStatus.PARTIAL_HANDLE.getCode().equals(Integer.parseInt(orderPageQueryResponse.getStatusCode()))
            || OrderStatus.COMPLETED.getCode().equals(Integer.parseInt(orderPageQueryResponse.getStatusCode()))) {
                log.error("该换货订单不是待处理状态无法删除，订单号：" + sapDeleteSaleOrderRequest.getOutOrderId());
                throw new FacadeException("OTS-05-001-10-16-046", sapDeleteSaleOrderRequest.getOutOrderId());
            }
        } else {
            //其他订单不是待交货状态就报错
            if (OrderStatus.PARTIAL_DELIVER.getCode().equals(Integer.parseInt(orderPageQueryResponse.getStatusCode()))
            || OrderStatus.COMPLETED.getCode().equals(Integer.parseInt(orderPageQueryResponse.getStatusCode()))) {
                log.error("该销售订单不是待交货状态无法删除，订单号：" + sapDeleteSaleOrderRequest.getOutOrderId());
                throw new FacadeException("OTS-05-001-10-16-044", sapDeleteSaleOrderRequest.getOutOrderId());
            }
        }
        OrderQueryRequest orderQueryRequest = new OrderQueryRequest();
        orderQueryRequest.setId(orderPageQueryResponse.getId());
        OrderSDO orderSDO = orderQueryServiceRepository.querySingle(orderQueryRequest);
        List<String> orderLineIds = new ArrayList<>();
        orderSDO.getOrderLineSDOS().forEach(orderLineSDO -> {
            //拒绝原因
            orderLineSDO.setRefuseReasonCode("05");
            orderLineIds.add(orderLineSDO.getId());
        });
        TradeMessageSDO tradeMessageSDO = new TradeMessageSDO();
        tradeMessageSDO.setOrderSDO(orderSDO);
        tradeMessageSDO.setAffectLineIds(orderLineIds);
        String message = JSON.toJSONString(tradeMessageSDO);
        Map<String, String> map = new HashMap<>();
        map.put("_CZ_KEY", BcOtsConstants.TENANT_ID());
        messageService.sendMessage("sale_order_message", "CR_SALEORDER", "SaleRefused", orderSDO.getOrderBizId(), message, map);
        log.info("order message = " + message);

        OrderWriteEntity orderWriteEntity = OrderWriteFactory.buildOrderEntity(orderSDO);
        orderWriteEntity.deleteOrder();
        return Result.success(true);
    }

    public Result<Boolean> deleteAllocateOrder(AllocateOrder allocateOrder) {
        //查询总部销售调拨单子单 循环调拨单子单并且删除子单 最后删除该总部销售调拨单；循环调拨单子单同时根据预报单号和货品id查询对应预报单子单 更新预报字段回复数量/状态 最后更新预报主单
        try {
            AllocateOrderDetailLoadListRequest allocateOrderDetailLoadListRequest =  new AllocateOrderDetailLoadListRequest();
            allocateOrderDetailLoadListRequest.setAllocateOrderId(String.valueOf(allocateOrder.getId()));
            Result<List<AllocateOrderDetail>> allocteOrderDetailResult = allocateOrderDetailService.loadAllocateOrderDetailList(allocateOrderDetailLoadListRequest);
            log.info("019查调拨明细单 结果: {} ",JSONObject.toJSONString(allocteOrderDetailResult));
            if (allocteOrderDetailResult != null && CollectionUtils.isNotEmpty(allocteOrderDetailResult.getResult())) {
                for (AllocateOrderDetail allocateOrderDetail : allocteOrderDetailResult.getResult()) {
                    Integer quantity = StringConverter.StringToInteger(allocateOrderDetail.getQuantity());
                    //删除调拨单子单
                    DeleteAllocateOrderDetailRequest deleteAllocateOrderDetailRequest = new DeleteAllocateOrderDetailRequest();
                    deleteAllocateOrderDetailRequest.setId(String.valueOf(allocateOrderDetail.getId()));
                    allocateOrderDetailService.deleteAllocateOrderDetail(deleteAllocateOrderDetailRequest);

                    //有的调拨单没有关联预报单就不处理预报单逻辑
                    if (allocateOrder.getAllocateApplyOrderId() != null) {
                        //根据调拨预报单号和货品id查询对应调拨预报单明细  并根据查询预报明细单id更新回复数量和状态
                        AllocateApplyOrderDetailLoadListRequest allocateApplyOrderDetailLoadListRequest = new AllocateApplyOrderDetailLoadListRequest();
                        allocateApplyOrderDetailLoadListRequest.setAllocateApplyOrderId(Integer.valueOf(allocateOrder.getAllocateApplyOrderId()));
                        allocateApplyOrderDetailLoadListRequest.setGoodsId(allocateOrderDetail.getScItemId());
                        Result<List<AllocateApplyOrderDetail>> allocateApplyOrderDetailResult = allocateApplyOrderDetailService.loadAllocateApplyOrderDetailList(allocateApplyOrderDetailLoadListRequest);
                        log.info("019查调拨预报明细单 参数: {} 结果: {} ",JSONObject.toJSONString(allocateApplyOrderDetailLoadListRequest),JSONObject.toJSONString(allocateApplyOrderDetailResult));
                        if (allocateApplyOrderDetailResult != null && CollectionUtils.isNotEmpty(allocateApplyOrderDetailResult.getResult())) {
                            AllocateApplyOrderDetail  applyOrderDetail = allocateApplyOrderDetailResult.getResult().get(0);
                            //更新对应的预报单明细单
                            AllocateApplyOrderDetail allocateApplyOrderDetail = new AllocateApplyOrderDetail();
                            allocateApplyOrderDetail.setId(applyOrderDetail.getId());
                            allocateApplyOrderDetail.setReplyQuantity(applyOrderDetail.getReplyQuantity() - quantity);
                            //回复数量回滚至0 状态更新为待回复 反之更新为部分回复
                            if (applyOrderDetail.getReplyQuantity() - quantity <= 0) {
                                allocateApplyOrderDetail.setStatus(AllocateApplyOrderStatusEnum.WAIT_ANSWER.getCode());
                            } else {
                                allocateApplyOrderDetail.setStatus(AllocateApplyOrderStatusEnum.PART_ANSWER.getCode());
                            }
                            allocateApplyOrderDetailService.updateAllocateApplyOrderDetail(allocateApplyOrderDetail);
                        }
                    }
                }
            }

            //有的调拨单没有关联预报单就不处理预报单逻辑
            if (allocateOrder.getAllocateApplyOrderId() != null) {
                //根据总部销售调拨单的预报单单号 查所有的预报单明细 判断其中回复数量 只要其中有回复数量大于0的 这更新预报主单状态为部分回复 反之更新为待回复
                boolean isStatus = false;
                AllocateApplyOrderDetailLoadListRequest allocateApplyOrderDetailLoadListRequest = new AllocateApplyOrderDetailLoadListRequest();
                allocateApplyOrderDetailLoadListRequest.setAllocateApplyOrderId(Integer.valueOf(allocateOrder.getAllocateApplyOrderId()));
                Result<List<AllocateApplyOrderDetail>> allocateApplyOrderDetailResult = allocateApplyOrderDetailService.loadAllocateApplyOrderDetailList(allocateApplyOrderDetailLoadListRequest);
                log.info("019查调拨明细单 结果: {} ",JSONObject.toJSONString(allocateApplyOrderDetailResult));
                if (allocateApplyOrderDetailResult != null && CollectionUtils.isNotEmpty(allocateApplyOrderDetailResult.getResult())) {
                    for (AllocateApplyOrderDetail allocateApplyOrderDetail : allocateApplyOrderDetailResult.getResult()) {
                        //判断子单是否有部分回复状态
                        if (AllocateApplyOrderStatusEnum.PART_ANSWER.getCode().equals(allocateApplyOrderDetail.getStatus())) {
                            isStatus = true;
                            break;
                        }
                    }
                }
                AllocateApplyOrder allocateApplyOrder = new AllocateApplyOrder();
                allocateApplyOrder.setId(Long.valueOf(allocateOrder.getAllocateApplyOrderId()));
                if (isStatus) {
                    allocateApplyOrder.setStatus(AllocateStatusEnum.PART_ANSWER.getCode());
                } else {
                    allocateApplyOrder.setStatus(AllocateStatusEnum.WAIT_ANSWER.getCode());
                }
                allocateApplyOrderService.updateAllocateApplyOrder(allocateApplyOrder);
            }


            //最后删除该总部销售调拨单
            DeleteAllocateOrderRequest deleteAllocateOrderRequest = new DeleteAllocateOrderRequest();
            deleteAllocateOrderRequest.setId(String.valueOf(allocateOrder.getId()));
            allocateOrderService.deleteAllocateOrder(deleteAllocateOrderRequest);
        } catch (Exception e) {
            log.error("019 deleteAllocateOrder error" + e.getMessage());
            return Result.fail(null,e.getMessage());
        }
        log.info("019删除总部销售调拨单及明细单！！！");
        return Result.success(true);
    }

    @Override
    @ProcessInvoker
    public Result<Void> generateOrder(GenerateOrderRequest generateOrderRequest) {
        log.info("OrderServiceImpl generateOrder requestParams:" + JSONObject.toJSONString(generateOrderRequest));
        if (StringUtils.isEmpty(generateOrderRequest.getOutMaterialCertificateId()) || StringUtils.isEmpty(generateOrderRequest.getAllocateId())) {
            return Result.fail("OTS-05-001-10-16-028", "物料凭证或者调拨单号为空");
        }
        try {
            //此处幂等方案，先将物料凭证放入缓存1天，后续通过es查询是否存在，通过此种方式绕过纪元的模型改动
            boolean lock = epochCacheService.setIfAbsent(SaleOrderConstants.SALE_ORDER_REDIS_CODE, generateOrderRequest.getOutMaterialCertificateId(), "");
            //获取到锁，表明可以新建,获取不到锁，表明是重复请求
            if (!lock) {
                log.info("物料凭证重复:" + generateOrderRequest.getOutMaterialCertificateId());
                return Result.success(null);
            }
            epochCacheService.expire(SaleOrderConstants.SALE_ORDER_REDIS_CODE, generateOrderRequest.getOutMaterialCertificateId(), 30L, TimeUnit.MINUTES);
            //获取到锁 仍然需要校验一下是否已经存在
            PageQueryOrderEsListRequest pageQueryOrderEsListRequest = new PageQueryOrderEsListRequest();
            pageQueryOrderEsListRequest.setMaterialnoList(Lists.newArrayList(generateOrderRequest.getOutMaterialCertificateId()));
            Result<List<OrderPageQueryResponse>> resultEs = orderQueryServiceRepository.pageQueryES(pageQueryOrderEsListRequest);
            if (resultEs != null && CollectionUtils.isNotEmpty(resultEs.getResult())) {
                log.info("物料凭证重复:" + generateOrderRequest.getOutMaterialCertificateId());
                return Result.success(null);
            }
            AllocateOrderDetailsQueryRequest request = new AllocateOrderDetailsQueryRequest();
            request.setAllocateOrderId(generateOrderRequest.getAllocateId());
            request.setOutAllocateOrderId(generateOrderRequest.getOuterAllocateId());
            Result<AllocateOrderDetailsQueryResponse> result = allocateOrderReadService.query(request);
            log.info("allocateOrderReadService query response:" + JSONObject.toJSONString(generateOrderRequest));
            if (!result.isSuccess() || result.getResult() == null) {
                throw new FunctionException("OTS-05-001-10-16-010", "查询调拨单失败");
            }
            AllocateOrderDetailsQueryResponse allocateOrder = result.getResult();
            if (allocateOrder == null) {
                throw new FunctionException("OTS-05-001-10-16-011", "未查询到调拨单");
            }

            OrderSDO orderSDO = new OrderSDO();
//        DeliverOrderSDO deliverOrderSDO = new DeliverOrderSDO();


//        orderSDO.setOrderLineSDOS(convert(allocateOrder.getCustomer(), generateOrderRequest.getScItemList()));
            orderSDO.setCustomerCode(allocateOrder.getCustomer());
            orderSDO.setCustomerName(allocateOrder.getCustomerName());
            orderSDO.setOrganizationCode(allocateOrder.getApplyOrgId());
            orderSDO.setOrganizationName(allocateOrder.getApplyOrgName());
            orderSDO.setReceiveAddressCode(allocateOrder.getAddressCode());
            orderSDO.setWareHouseCode(generateOrderRequest.getWareHouseAreaId());

            QueryAddressRequest queryAddressRequest = new QueryAddressRequest();
            queryAddressRequest.setAddressCode(allocateOrder.getBranchCustomersCode());
            queryAddressRequest.setCustomerCode(allocateOrder.getBranchCustomersCode());

            Result<List<CustomerAddressSDO>> listResult = customerAddressQueryService.pageQueryCustomerAddress(queryAddressRequest);
            if (!listResult.isSuccess() || CollectionUtils.isEmpty(listResult.getResult())) {
                throw new FunctionException("OTS-05-001-10-16-014", "未查询到客户收货地址数据");
            }

            CustomerAddressSDO customerAddressSDO = listResult.getResult().get(0);
            if (StringUtils.isBlank(customerAddressSDO.getOrgSaleOrganizationCode())) {
                throw new FunctionException("OTS-05-001-10-16-015", "未查询到客户组织编码");

            }
            orderSDO.setOrganizationCode(customerAddressSDO.getOrgSaleOrganizationCode());
            orderSDO.setOrganizationName(customerAddressSDO.getOrgSalesOrganizationName());

            QueryGenerateOrderSwitchRequest queryGenerateOrderSwitchRequest = new QueryGenerateOrderSwitchRequest();
            queryGenerateOrderSwitchRequest.setOrganizationCode(customerAddressSDO.getOrgSaleOrganizationCode());
            queryGenerateOrderSwitchRequest.setStrategyType(StrategyTypeEnum.GENERATE_SWITCH.getCode());
            Result<Boolean> booleanResult = strategyQueryService.queryGenerateOrderSwitch(queryGenerateOrderSwitchRequest);
            if (Objects.isNull(booleanResult) || Objects.isNull(booleanResult.getResult()) || !booleanResult.getResult()) {
                log.error("策略效验返回为false:" + JSONObject.toJSONString(booleanResult));
                epochCacheService.remove(SaleOrderConstants.SALE_ORDER_REDIS_CODE, Lists.newArrayList(generateOrderRequest.getOutMaterialCertificateId()));
                return Result.success(null);
            }

//        orderSDO.setAddressCode(customerAddressSDO.getAddress());
            orderSDO.setReceiveAddressCode(customerAddressSDO.getAddressCode());
            orderSDO.setReceiveDetailAddress(customerAddressSDO.getAddressName());
            orderSDO.setDepartmentCode(customerAddressSDO.getOrgSaleDepartmentCode());
            orderSDO.setDepartmentName(customerAddressSDO.getOrgSalesDepartmentName());
            orderSDO.setSaleChannelCode(customerAddressSDO.getOrgSaleChannelCode());
            orderSDO.setSaleChannelName(customerAddressSDO.getOrgSalesChannelName());
            orderSDO.setChannelCode(customerAddressSDO.getChannelCode());
            orderSDO.setChannelName(customerAddressSDO.getChannelName());
            orderSDO.setContactor(customerAddressSDO.getContactName());
            orderSDO.setContactorPhone(customerAddressSDO.getCellphoneNumber());
//        orderSDO.setReceiveDetailAddress(customerAddressSDO.getReceiveAddress());
            orderSDO.setProductGroupCode(allocateOrder.getProductGroup());
            orderSDO.setProductGroupName(allocateOrder.getProductGroupDesc());
            orderSDO.setCustomerCode(customerAddressSDO.getCustomerCode());
            orderSDO.setCustomerName(customerAddressSDO.getCustomerName());
            orderSDO.setSalesmanId(customerAddressSDO.getPrincipal());
            orderSDO.setSalesmanName(customerAddressSDO.getPrincipalName());
//        orderSDO.setDeliveryTime(new Date());
            if (allocateOrder.getShipMethod() != null) {
                orderSDO.setTransportModeCode("0" + allocateOrder.getShipMethod());
                orderSDO.setTransportModeName(allocateOrder.getShipMethodDesc());
            }

//        orderSDO.setId();
//        orderSDO.setFrontOrderId();
//        orderSDO.setBizCode();
//        orderSDO.setBusinessCode();

            orderSDO.setStatus(OrderStatus.BEFORE_DELIVERY.getCode());
            orderSDO.setStatusDesc(OrderStatus.BEFORE_DELIVERY.getDesc());
//        orderSDO.setCreateReason();
            orderSDO.setDeliveryStatus(OrderStatus.BEFORE_DELIVERY.getCode());

            orderSDO.setFeatures(new HashMap<String, String>() {{
                if (Objects.nonNull(allocateOrder.getId())) {
                    put(SaleOrderConstants.ALLOCATE_ORDER_ID, String.valueOf(allocateOrder.getId()));
                }
                if (StringUtils.isNotBlank(allocateOrder.getAllocateApplyOrderCode())) {
                    put(SaleOrderConstants.ALLOCATE_ORDER_BIZ_ID, allocateOrder.getAllocateApplyOrderCode());
                }
                if (StringUtils.isNotBlank(allocateOrder.getOutAllocateOrderId())) {
                    put(SaleOrderConstants.STO_SAP_ORDER_ID, allocateOrder.getAllocateApplyOrderId());
                }
                if (Objects.nonNull(generateOrderRequest.getOutMaterialCertificateId())) {
                    put(SaleOrderConstants.MATERIAL_CER_ID, String.valueOf(generateOrderRequest.getOutMaterialCertificateId()));
                }
            }});
            orderSDO.setCreatorId("0");
            orderSDO.setCreatorName("系统");
            orderSDO.setSyncVersion(0);

            //add by 皓晖 at 20211215 for 工厂直发自动生成销售订单时,给sap发送分公司的"创建销售订单014接口报文"缺少发货仓字段 begin
            String wareHouseAreaId = generateOrderRequest.getWareHouseAreaId();
            if (StringUtils.isNotEmpty(wareHouseAreaId)) {
                WarehouseInfo warehouseInfo = this.getWarehouseInfo(wareHouseAreaId);
                if (warehouseInfo != null) {
                    orderSDO.setWareHouseCode(warehouseInfo.getId());
                    orderSDO.setWareHouseName(warehouseInfo.getName());
                }
            }
            //add by 皓晖 at 20211215 for 工厂直发自动成销售订单时,给sap发送分公司的"创建销售订单014接口报文"缺少发货仓字段 end

            orderSDO.setCustomerReferenceNumber(allocateOrder.getSapRefPoNo());
            orderSDO.setCustomerExpectDate(allocateOrder.getExpectedDeliveryDate());
            orderSDO.setCostCenter(allocateOrder.getSapCostCenter());
            orderSDO.setModifierId("0");
            orderSDO.setGmtCreate(new Date());
            orderSDO.setGmtModified(new Date());
            orderSDO.setModifierName("系统");
            orderSDO.setOrderTag("normal");
            orderSDO.setOrderType(SaleOrderTag.STD_ORDER.getCode());
            orderSDO.setOrderTypeName(SaleOrderTag.STD_ORDER.getDesc());


            if (CollectionUtils.isNotEmpty(generateOrderRequest.getScItemList())) {
                List<ScItemDetail> scItemList = generateOrderRequest.getScItemList();

                List<String> scItemIds = scItemList.stream().map(ScItemDetail::getScItemId).collect(Collectors.toList());
                SearchScItemRequest searchScItemRequest = new SearchScItemRequest();
                SearchReqDTO searchReqDTO = new SearchReqDTO();
                searchReqDTO.setScItemIds(scItemIds);
                searchScItemRequest.setSearchReqDTO(searchReqDTO);
                searchScItemRequest.setPageNum(1);
                searchScItemRequest.setPageSize(scItemIds.size());
                Result<List<com.epoch.app.bcots.model.dto.ScItemSDO>> scItemListResp = baseDataService.searchScItem(searchScItemRequest);

                Map<String, ForecastOrderLineSDO> hashMap = new HashMap<>();
                if (Objects.nonNull(scItemListResp) && CollectionUtils.isNotEmpty(scItemListResp.getResult())) {
                    hashMap = scItemListResp.getResult().stream().collect(Collectors.toMap(com.epoch.app.bcots.model.dto.ScItemSDO::getScItemId, t -> {

                        ForecastOrderLineSDO forecastOrderLineSDO = new ForecastOrderLineSDO();
                        forecastOrderLineSDO.setScItemId(t.getScItemId());
                        forecastOrderLineSDO.setScItemTitle(t.getTitle());
                        forecastOrderLineSDO.setScItemOutCode(t.getOuterId());
                        forecastOrderLineSDO.setGoodsCode(t.getOuterId());
                        Map<String, String> features = t.getFeatures();
                        if (MapUtils.isNotEmpty(features)) {
                            String unitName = features.get("unit");
                            String unitCode = features.get("unitName");
                            if (org.apache.commons.lang3.StringUtils.isNotBlank(unitName)) {
                                forecastOrderLineSDO.setInventoryUnit(unitName);
                            }
                            if (org.apache.commons.lang3.StringUtils.isNotBlank(unitCode)) {
                                forecastOrderLineSDO.setInventoryUnitCode(unitCode);
                            }
                        }
                        return forecastOrderLineSDO;
                    }));
                }


                Map<String, ForecastOrderLineSDO> finalHashMap = hashMap;

                List<ForecastOrderLineSDO> lineSDOList = scItemList.stream().map(scItemDetail -> {

                    ForecastOrderLineSDO lineSDO = new ForecastOrderLineSDO();
                    lineSDO = finalHashMap.get(scItemDetail.getScItemId());

                    lineSDO.setQuantity(scItemDetail.getSaleUnitQuantity());
                    lineSDO.setSaleUnitCode(scItemDetail.getSaleUnit());

                    QuerySaleUnitRequest querySaleUnitRequest = QuerySaleUnitRequest.builder().scItemId(scItemDetail.getScItemId()).build();
                    querySaleUnitRequest.setInventoryUnit(lineSDO.getInventoryUnit());
                    querySaleUnitRequest.setInventoryUnitCode(lineSDO.getInventoryUnitCode());
                    querySaleUnitRequest.setUnitConvert("1");
                    Result<List<SelectCombox>> querySaleUnitList = forecastOrderLineQueryService.querySaleUnitList(querySaleUnitRequest);
                    if (querySaleUnitList.isSuccess() && Objects.nonNull(querySaleUnitList.getResult())) {
                        List<SelectCombox> saleUnitListResult = querySaleUnitList.getResult();
                        Map<String, SelectCombox> unitMap = new HashMap<>();
                        Nullable.stream(saleUnitListResult).forEach(t -> {
                            unitMap.put(t.getValue(), t);
                        });
                        SelectCombox selected = unitMap.get(lineSDO.getSaleUnitCode());
                        if (selected != null) {
                            lineSDO.setSaleUnit(selected.getLabel());
                            lineSDO.setUnitConvert(selected.getExt());
                        }

                        SelectCombox inventoryMap = unitMap.get(lineSDO.getSaleUnitCode());
                        if (inventoryMap != null) {
                            lineSDO.setInventoryUnit(inventoryMap.getLabel());
                        }
                    }
                    return lineSDO;
                }).collect(Collectors.toList());


                QueryGoodsDetailForMiniprogrameRequest goodsDetail = new QueryGoodsDetailForMiniprogrameRequest();
                goodsDetail.setGoodsList(lineSDOList);
                goodsDetail.setAddressCode(allocateOrder.getBranchCustomersCode());
                QueryGoodsDetailForMiniprogrameResponse goodsDetailResp = otsForecastSalesService.queryGoodsDetailForMiniprograme(goodsDetail);

                if (Objects.nonNull(goodsDetailResp) && Objects.nonNull(goodsDetailResp.getResult()) && CollectionUtils.isNotEmpty(goodsDetailResp.getResult().getForecastOrderLineSDOList())) {
                    List<ForecastOrderLineSDO> forecastOrderLineSDO = goodsDetailResp.getResult().getForecastOrderLineSDOList();
                    AtomicInteger count = new AtomicInteger(1);
                    List<OrderLineSDO> orderLineSDOS = forecastOrderLineSDO.stream().map(o -> {
                        OrderLineSDO orderLineSDO = new OrderLineSDO();
                        //行号
                        orderLineSDO.setSerialNumber(String.valueOf(count.get() * 10));
                        count.set(count.get() + 1);
                        ScItemSDO scItemSDO = new ScItemSDO();
                        BeanUtils.copyProperties(o, scItemSDO, "goodsProductationTime");
                        scItemSDO.setScItemId(o.getScItemId());
                        scItemSDO.setScItemTitle(o.getScItemTitle());
                        scItemSDO.setInventoryUnitCode(o.getInventoryUnitCode());
                        scItemSDO.setInventoryUnitName(o.getInventoryUnit());
                        scItemSDO.setSaleUnit(o.getSaleUnitCode());
                        scItemSDO.setSaleUnitName(o.getSaleUnit());
                        scItemSDO.setProductGroupCode(customerAddressSDO.getItemGroup());
                        scItemSDO.setProductGroupCode(customerAddressSDO.getItemGroupName());
                        scItemSDO.setScItemOutCode(o.getGoodsCode());
                        scItemSDO.setQuantity(((Number) Double.parseDouble(o.getQuantity())).intValue());
                        if (StringUtils.isNotBlank(o.getExt1()) && ((Number) Double.parseDouble(o.getExt1())).longValue() > 0) {
                            scItemSDO.setUnitPrice(((Number) Double.parseDouble(o.getExt1())).longValue());
                        } else {
                            throw new FunctionException("OTS-05-001-10-16-023", "物料编码:" + o.getScItemId() + ",单价:" + o.getUnitPrice());
                        }

                        scItemSDO.setProductGroupCode(customerAddressSDO.getItemGroup());
                        scItemSDO.setProductGroupName(customerAddressSDO.getItemGroupName());

                        //todo ,if unitPrice or totalFee is null ,zero,negative number,throw new exception
                        orderLineSDO.setScItemSDO(scItemSDO);
                        orderLineSDO.setCustomerCode(customerAddressSDO.getCustomerCode());
                        orderLineSDO.setStatus(OrderStatus.STAY_PUSH.getCode());
                        if (StringUtils.isNotBlank(o.getExt2())) {
                            orderLineSDO.setShouldPayFee(((Number) Double.parseDouble(o.getExt2())).longValue());
//                            orderLineSDO.setActualPaidFee(((Number) Double.parseDouble(o.getExt2())).longValue());
                        }
                        orderLineSDO.setCreatorId("0");
                        orderLineSDO.setCreatorName("系统");
                        orderLineSDO.setModifierId("0");
                        orderLineSDO.setModifierName("系统");
                        orderLineSDO.setGmtCreate(new Date());
                        orderLineSDO.setGmtModified(new Date());
                        return orderLineSDO;
                    }).collect(Collectors.toList());

                    orderSDO.setOrderLineSDOS(orderLineSDOS);
                }
            }

            //调拨无需成本中心
            orderSDO.setCostCenter(null);
            SaveSaleOrderRequest saveSaleOrderRequest = new SaveSaleOrderRequest();
            saveSaleOrderRequest.setOrderSDOS(Lists.newArrayList(orderSDO));
            Result resp = this.saveSaleOrder(saveSaleOrderRequest);
        } catch (FunctionException e) {
            e.printStackTrace();
            log.error("生成销售订单异常", e);
            epochCacheService.remove(SaleOrderConstants.SALE_ORDER_REDIS_CODE, Lists.newArrayList(generateOrderRequest.getOutMaterialCertificateId()));
            throw new FacadeException(e);
//            return Result.fail(e.getErrorCode(),e.getMessage());

        }
        return Result.success(null);
    }

    /**
     * 查询逻辑仓信息
     */
    private WarehouseInfo getWarehouseInfo(String wareHouseId) {
        log.info("查询仓库请求信息:" + wareHouseId);
        WarehouseInfo warehouseInfo = null;
        if (StringUtils.isNotEmpty(wareHouseId)) {
            QueryWarehouseByIdRequest request = new QueryWarehouseByIdRequest();
            request.setId(wareHouseId);
            Result<WarehouseInfo> result = unifiedInventoryService.queryWarehouseById(request);
            warehouseInfo = result.getResult();
        }
        log.info("查询仓库返回信息:" + JSON.toJSONString(warehouseInfo));
        return warehouseInfo;
    }

    @Override
    @FacadeInvoker
    public Result<Boolean> rejectOrder(RejectOrderRequest request) {
        //获取当前登录人
        EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse = bcOtsService.employeeGetCurrentLogin();
        Boolean aBoolean = orderWriteRepository.rejectOrder(request);
        OpLogModel.OpLogModelBuilder<String> builder = OpLogModel.builder();
        OpLogModel<String> opLogModel = builder.build();
        opLogModel.setModuleName(ModuleEnum.SALES.getModuleName());
        opLogModel.setModuleId(String.valueOf(ModuleEnum.SALES.getModuleId()));
        opLogModel.setObjectId(request.getId());
        opLogModel.setObjectName("so_order_id");
        opLogModel.setOperateType(OrderOperateType.CREATE.getCode());
        opLogModel.setOperatorType(OperatorType.USER.getOperatorType());
        Map<String, String> map = new HashMap<>();
        if (StringUtils.isNotBlank(employeeGetCurrentLoginResponse.getEmployeeId()) && StringUtils.isNotBlank(employeeGetCurrentLoginResponse.getEmployeeName())) {
            opLogModel.setOperatorId(employeeGetCurrentLoginResponse.getEmployeeId());
            map.put("name", employeeGetCurrentLoginResponse.getEmployeeName());
            //opLogModel.setFeatures(employeeGetCurrentLoginResponse.getEmployeeName());
        }
        map.put("active", OrderOperateType.REFUSE.getDesc());
        String logInfo = JSONObject.toJSONString(map);
        opLogModel.setFeatures(logInfo);
        log.asyncMonitorObjectChangeV2(opLogModel);
        return Result.success(aBoolean);
    }

    @Override
    @FacadeInvoker
    public Result<List<ImportOrderRequest>> excelImportOrderList(ExcelImportOrderListRequest excelImportOrderListRequest) {

        log.info("ExcelImportOrderListRequest  excelImportOrderListRequest:" + JSONObject.toJSONString(excelImportOrderListRequest));

        //获取当前登录人
        EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse = bcOtsService.employeeGetCurrentLogin();

        // 获取登陆人 所属组织code
        List<OrganizationSDO> loginOrganizationCodeList = getLoginOrganizationCode(OrganizationTypeEnum.SALES_ORGANIZATION.getCode());
        List<String> loginOrganizationCodes = loginOrganizationCodeList.stream().map(OrganizationSDO::getCode).collect(Collectors.toList());

        // 获取登陆人 业务渠道code
        List<String> organizationIds = loginOrganizationCodeList.stream().map(OrganizationSDO::getId).collect(Collectors.toList());
        List<String> channelCode = businessChannelCodes(organizationIds);

        // 获取登陆人 仓库权限
        List<String> warehouseCodes = getWarehouseCodes();

        Set<String> importAddressCodes = excelImportOrderListRequest.getImportOrderList().stream()
                .filter(a -> StringUtils.isNotBlank(a.getReceiveAddressCode()))
                .map(ImportOrderRequest::getReceiveAddressCode)
                .collect(Collectors.toSet());
        // 获取登录人 收货地址权限
        Map<String, List<CustomerAddressSDO>> customerListMap = addressLists(new ArrayList<>(importAddressCodes), employeeGetCurrentLoginResponse);
        List<String> addressCodes = new ArrayList<>(customerListMap.keySet());

        //结果数组
        List<ImportOrderRequest> resultList = new ArrayList<>();
        //异常数组
        List<ImportOrderRequest> errorList = new ArrayList<>();
        //第一步数据校验的成功的数组
        List<ImportOrderRequest> successList = new ArrayList<>();
        //库存校验成功的数组
        List<ImportOrderRequest> checkStockList = new ArrayList<>();
        //去重后子单集合
        List<ImportOrderRequest> removeRepeatOrderLineList = new ArrayList<>();
        //创单成功的数组
        List<ImportOrderRequest> saveSuccessList = new ArrayList<>();

        List<ImportOrderRequest> importOrderList = excelImportOrderListRequest.getImportOrderList();
        //对列表中的数据进行校验如果编码不存在就加入错误信息然后返回
        Map<String, List<ImportOrderRequest>> check = Nullable.stream(importOrderList).filter(importOrderRequest -> {

            //校验导入订单类型
            if (StringUtils.isNotBlank(excelImportOrderListRequest.getOrderTag())) {
                Boolean flag = checkOrderType(excelImportOrderListRequest.getOrderTag(), importOrderRequest);
                if (!flag) {
                    importOrderRequest.setErrorMessage("导入的订单类型不符");
                    errorList.add(importOrderRequest);
                    return false;
                }
            }


            if (StringUtils.isBlank(importOrderRequest.getCustomerReferenceNo())) {
                importOrderRequest.setErrorMessage("客户参考号不能为空");
                errorList.add(importOrderRequest);
                return false;
            } else {
                importOrderRequest.setCustomerReferenceNo(importOrderRequest.getCustomerReferenceNo().trim());
                if (importOrderRequest.getCustomerReferenceNo().contains(" ")
                        || PATTERN_SPECIAL_STRING.matcher(importOrderRequest.getCustomerReferenceNo()).matches()) {
                    importOrderRequest.setErrorMessage("客户参考号不能有特殊字符");
                    return false;
                } else {
                    return true;
                }
            }
        }).collect(Collectors.groupingBy(ImportOrderRequest::getCustomerReferenceNo));
        boolean tag = true;
        String ErrorMessage = "";
        for (String s : check.keySet()) {
            tag = true;
            ErrorMessage = "";
            List<ImportOrderRequest> importOrderRequests = check.get(s);
            //根据客户参考号下的数据遍历
            for (ImportOrderRequest importOrderRequest : importOrderRequests) {

                // 校验仓库信息 填写以填写为准，否则系统根据供货关系默认
                if (StringUtils.isBlank(importOrderRequest.getWareHouseCode())) {
                    List<CustomerAddressSDO> customerAddressSDOS = customerListMap.get(importOrderRequest.getReceiveAddressCode());
                    if (!CollectionUtils.isEmpty(customerAddressSDOS)) {
                        CustomerAddressSDO customerAddressSDO = customerAddressSDOS.get(0);
                        // 销售部门 需要 作为入参
                        QueryAllocateRelationForOrderRequest request = QueryAllocateRelationForOrderRequest.builder()
                                .organizationCode(importOrderRequest.getOrganizationCode())
                                .saleChannelCode(customerAddressSDO.getOrgSaleChannelCode())
                                .customerCode(customerAddressSDO.getCustomerCode())
                                .saleDepartmentCode(customerAddressSDO.getOrgSaleDepartmentCode()).build();
                        Result<List<AllocateRelationSDO>> listResult = allocateRelationReadService.queryAllocateRelationForOrder(request);
                        if (!ObjectUtils.isEmpty(listResult) && !CollectionUtils.isEmpty(listResult.getResult())) {
                            importOrderRequest.setWareHouseCode(listResult.getResult().get(0).getWareHouseCode());
                        }
                    }
                }

                // 校验 导入信息 是否符合登陆人权限
                String errorMessage = importCheckErrorMessage(importOrderRequest, loginOrganizationCodes, channelCode, warehouseCodes, addressCodes);
                if (StringUtils.isNotBlank(errorMessage)) {
                    ErrorMessage = errorMessage;
                    tag = false;
                    break;
                }


//                //校验组织编码
//                if (StringUtils.isNotBlank(importOrderRequest.getOrganizationCode())) {
//                    //获取组织名称
//                    GetOrganizationsByOutCodesRequest request = new GetOrganizationsByOutCodesRequest();
//                    List<String> list = new ArrayList<>();
//                    list.add(importOrderRequest.getOrganizationCode());
//                    request.setOutCodes(list);
//                    Result<List<OrganizationSDO>> result = organizationQueryService.getOrganizationsByOutCodes(request);
//                    if (!result.isSuccess() || CollectionUtils.isEmpty(result.getResult())) {
//                        ErrorMessage = "组织名称不存在";
//                        tag = false;
//                        break;
//                    }
//                }

                //校验渠道编码
//                if (StringUtils.isNotBlank(importOrderRequest.getChannelCode())) {
//                    QueryChannelRequest baselineBatchQueryChannelsRequest = new QueryChannelRequest();
//                    baselineBatchQueryChannelsRequest.setOutCode(importOrderRequest.getChannelCode());
//                    //调用查询渠道信息
//                    Result<ChannelResponse> result = channelService.queryChannelDetail(baselineBatchQueryChannelsRequest);
//                    if (!result.isSuccess() || Objects.isNull(result.getResult()) || Objects.isNull(result.getResult().getChannelId())) {
//                        ErrorMessage = "业务渠道不存在";
//                        tag = false;
//                        break;
//                    }
//                }


                //校验货品组信息
                if (StringUtils.isNotBlank(importOrderRequest.getProductGroupCode())) {
                    QueryScItemGroupRequest request = new QueryScItemGroupRequest();
                    request.setCode(importOrderRequest.getProductGroupCode());
                    Result<ScItemGroupResponse> result = scItemGroupQueryService.getScItemGroup(request);
                    if (!result.isSuccess() || Objects.isNull(result.getResult()) || Objects.isNull(result.getResult().getCode())) {
                        ErrorMessage = "货品组信息不存在";
                        tag = false;
                        break;
                    }
                } else {
                    ErrorMessage = "货品组信息不能为空";
                    tag = false;
                    break;
                }
                //校验货品信息
                SearchScItemRequest searchScItemRequest = new SearchScItemRequest();
                SearchReqDTO searchReqDTO = new SearchReqDTO();
                List<String> list = new ArrayList<>();
                list.add(importOrderRequest.getScItecmId());
                searchReqDTO.setOuterIdList(list);
                searchScItemRequest.setSearchReqDTO(searchReqDTO);
                Result<List<com.epoch.app.bcots.model.dto.ScItemSDO>> listResult = baseDataService.searchScItem(searchScItemRequest);
                if (!listResult.isSuccess() || CollectionUtils.isEmpty(listResult.getResult())) {
                    ErrorMessage = "货品信息不存在";
                    tag = false;
                    break;
                }
                //校验客户地址信息
//                if (StringUtils.isNotBlank(importOrderRequest.getReceiveAddressCode())) {
//                    QueryAddressRequest queryAddressRequest = new QueryAddressRequest();
//                    queryAddressRequest.setAddressCode(importOrderRequest.getReceiveAddressCode());
//                    Result<List<CustomerAddressSDO>> customerAddress = customerAddressQueryService.pageQueryCustomerAddress(queryAddressRequest);
//                    if (!listResult.isSuccess() || CollectionUtils.isEmpty(customerAddress.getResult()) || Objects.isNull(customerAddress.getResult().get(0))) {
//                        ErrorMessage = "客户地址信息不存在";
//                        tag = false;
//                        break;
//                    }
//                }


                //校验发货仓库信息
//                if (StringUtils.isNotBlank(importOrderRequest.getWareHouseCode())) {
//                    WmsQueryWarehouseZoneListRequest byIdRequest = new WmsQueryWarehouseZoneListRequest();
//                    byIdRequest.setCode(importOrderRequest.getWareHouseCode());
//                    WmsQueryWarehouseZoneListResponse warehouseInfoResult = unifiedInventoryService.wmsQueryWarehouseZoneList(byIdRequest);
//                    if (CollectionUtils.isEmpty(warehouseInfoResult.getResult()) || Objects.isNull(warehouseInfoResult.getResult().get(0))) {
//                        ErrorMessage = "发货仓库不存在";
//                        tag = false;
//                        break;
//                    }
//                }

            }
            if (tag) {
                successList.addAll(importOrderRequests);
            } else {
                String finalErrorMessage = ErrorMessage;
                Nullable.stream(importOrderRequests).forEach(it -> {
                    it.setErrorMessage(finalErrorMessage);
                    errorList.add(it);
                });
            }
        }


        //库存校验逻辑
        if (CollectionUtils.isNotEmpty(successList)) {
            Map<String, List<ImportOrderRequest>> collect = Nullable.stream(successList).collect(Collectors.groupingBy(ImportOrderRequest::getCustomerReferenceNo));
            for (String key : collect.keySet()) {
                List<ImportOrderRequest> importOrderRequests = collect.get(key);
                if (CollectionUtils.isNotEmpty(importOrderRequests) && Objects.nonNull(importOrderRequests.get(0))) {
                    boolean fag = true;
                    //校验库存
                    for (ImportOrderRequest importOrderRequest : importOrderRequests) {
                        // 标准销售订单&免费销售订单&现金销售订单创建 校验库存
                        if (SaleOrderTag.STD_ORDER.getCode().equals(importOrderRequest.getOrderType())
                                || SaleOrderTag.FREE_ORDER.getCode().equals(importOrderRequest.getOrderType())
                                || SaleOrderTag.CASH_ORDER.getCode().equals(importOrderRequest.getOrderType())) {
                            ImportOrderRequest importOrderRequest1 = excelCheckStock(importOrderRequest);
                            if (StringUtils.isNotEmpty(importOrderRequest1.getErrorMessage())) {
                                ErrorMessage = importOrderRequest1.getErrorMessage();
                                fag = false;
                                break;
                            }
                        }

                    }
                    if (fag) {
                        checkStockList.addAll(importOrderRequests);
                    } else {
                        String finalErrorMessage1 = ErrorMessage;
                        Nullable.stream(importOrderRequests).forEach(x -> {
                            x.setErrorMessage(finalErrorMessage1);
                            errorList.add(x);
                        });
                    }

                }
            }
        }

        // 重复子单校验
        if (CollectionUtils.isNotEmpty(checkStockList)) {
            Map<String, List<ImportOrderRequest>> collect = Nullable.stream(checkStockList).collect(Collectors.groupingBy(ImportOrderRequest::getCustomerReferenceNo));
            for (String key : collect.keySet()){
                List<String> scItemCodes = new ArrayList<>();
                List<ImportOrderRequest> importOrderRequests = collect.get(key);
                boolean flag = true;
                for (ImportOrderRequest it : importOrderRequests) {
                    String scItemId = it.getScItecmId();
                    String errorMessage = it.getErrorMessage();
                    if (StringUtils.isBlank(errorMessage) && !scItemCodes.contains(scItemId)) {
                        scItemCodes.add(scItemId);
                        continue;
                    }

                    for (ImportOrderRequest importOrderRequest : importOrderRequests) {
                        if (StringUtils.isBlank(importOrderRequest.getErrorMessage())) {
                            importOrderRequest.setErrorMessage(StringUtils.isNotBlank(errorMessage) ? "存在无效的子单行" : "存在重复的货品");
                        }
                        flag = false;
                    }

                    break;
                }
                if (flag) {
                    removeRepeatOrderLineList.addAll(importOrderRequests);
                }else {
                    errorList.addAll(importOrderRequests);
                }
            }
        }

        //创建销售订单逻辑
        if (CollectionUtils.isNotEmpty(removeRepeatOrderLineList)) {
            Map<String, List<ImportOrderRequest>> collect = Nullable.stream(removeRepeatOrderLineList).collect(Collectors.groupingBy(ImportOrderRequest::getCustomerReferenceNo));
            for (String key : collect.keySet()) {
                List<ImportOrderRequest> importOrderRequests = collect.get(key);
                if (CollectionUtils.isNotEmpty(importOrderRequests) && Objects.nonNull(importOrderRequests.get(0))) {
                    OrderSDO orderSDO = OrderSDO.builder()
                            .orderType(importOrderRequests.get(0).getOrderType().trim())
                            //标记
                            .remark(importOrderRequests.get(0).getOrderRemark())
                            .createReason(importOrderRequests.get(0).getCreateReason())
                            .status(OrderStatus.BEFORE_SUBMIT.getCode())//待提交
                            .organizationCode(importOrderRequests.get(0).getOrganizationCode())
                            .productGroupCode(importOrderRequests.get(0).getProductGroupCode())
                            .channelCode(importOrderRequests.get(0).getChannelCode())
                            .receiveAddressCode(importOrderRequests.get(0).getReceiveAddressCode())
                            .transportModeCode(importOrderRequests.get(0).getTransportModeCode())
                            .createReason(importOrderRequests.get(0).getCreateReason())
                            .wareHouseCode(importOrderRequests.get(0).getWareHouseCode())
                            .costCenter(importOrderRequests.get(0).getCostCenter())
                            .gmtCreate(new Date())
                            .customerReferenceNumber(importOrderRequests.get(0).getCustomerReferenceNo())
                            .remark(importOrderRequests.get(0).getOrderRemark()).build();
                    if (null != importOrderRequests.get(0).getCustomerExpectDate()) {
                        orderSDO.setCustomerExpectDate(DateUtils.string2Date(importOrderRequests.get(0).getCustomerExpectDate()));
                    } else {
                        //默认为当前时间后一天
                        Calendar cal = Calendar.getInstance();
                        cal.setTime(new Date());
                        cal.add(Calendar.DAY_OF_MONTH, 1);
                        orderSDO.setCustomerExpectDate(cal.getTime());
                    }

                    //查询销售组织信息
                    if (StringUtils.isNotBlank(orderSDO.getOrganizationCode())) {
                        GetOrganizationsByOutCodesRequest request = new GetOrganizationsByOutCodesRequest();
                        List<String> list = new ArrayList<>();
                        list.add(orderSDO.getOrganizationCode());
                        request.setOutCodes(list);
                        Result<List<OrganizationSDO>> result = organizationQueryService.getOrganizationsByOutCodes(request);
                        if (Objects.nonNull(result.getResult().get(0))) {
                            OrganizationSDO organizationSDO = result.getResult().get(0);
                            orderSDO.setOrganizationName(organizationSDO.getName());
                            orderSDO.setOrganizationCode(organizationSDO.getCode());
                        }

                    }

                    //查询业务渠道信息
                    if (StringUtils.isNotBlank(orderSDO.getChannelCode())) {
                        QueryChannelRequest baselineBatchQueryChannelsRequest = new QueryChannelRequest();
                        baselineBatchQueryChannelsRequest.setOutCode(orderSDO.getChannelCode());
                        //调用查询渠道信息
                        Result<ChannelResponse> result = channelService.queryChannelDetail(baselineBatchQueryChannelsRequest);
                        orderSDO.setChannelName(result.getResult().getChannelName());
                        orderSDO.setChannelCode(result.getResult().getChannelCode());
                    }

                    //查询货品组信息
                    if (StringUtils.isNotBlank(orderSDO.getProductGroupCode())) {
                        QueryScItemGroupRequest request = new QueryScItemGroupRequest();
                        request.setCode(orderSDO.getProductGroupCode());
                        Result<ScItemGroupResponse> result = scItemGroupQueryService.getScItemGroup(request);
                        orderSDO.setProductGroupName(result.getResult().getName());
                        orderSDO.setProductGroupCode(result.getResult().getCode());
                    }


                    //查询客户收货地址信息
                    if (StringUtils.isNotBlank(orderSDO.getReceiveAddressCode())) {
                        QueryAddressRequest queryAddressRequest = new QueryAddressRequest();
                        queryAddressRequest.setAddressCode(orderSDO.getReceiveAddressCode());
                        queryAddressRequest.setChannelCode(orderSDO.getChannelCode());
                        Result<List<CustomerAddressSDO>> listResult = customerAddressQueryService.pageQueryCustomerAddress(queryAddressRequest);
                        List<CustomerAddressSDO> collect1 = listResult.getResult().stream().filter(customerAddressSDO ->
                                StringUtils.isNotBlank(customerAddressSDO.getPrincipal())
                        ).collect(Collectors.toList());
                        if (Objects.nonNull(collect1.get(0))) {
                            CustomerAddressSDO customerAddressSDO = collect1.get(0);
                            orderSDO.setCustomerCode(customerAddressSDO.getCustomerCode());
                            orderSDO.setCustomerName(customerAddressSDO.getCustomerName());
                            orderSDO.setOrganizationCode(customerAddressSDO.getOrgSaleOrganizationCode());
                            orderSDO.setOrganizationName(customerAddressSDO.getOrgSalesOrganizationName());
                            orderSDO.setDepartmentCode(customerAddressSDO.getOrgSaleDepartmentCode());
                            orderSDO.setDepartmentName(customerAddressSDO.getOrgSalesDepartmentName());
                            orderSDO.setSaleChannelCode(customerAddressSDO.getOrgSaleChannelCode());
                            orderSDO.setSaleChannelName(customerAddressSDO.getOrgSalesChannelName());
                            orderSDO.setChannelCode(customerAddressSDO.getChannelCode());
                            orderSDO.setSalesmanName(customerAddressSDO.getPrincipalName());
                            orderSDO.setChannelName(customerAddressSDO.getChannelName());
                            orderSDO.setReceiveDetailAddress(customerAddressSDO.getAddressName());
                            orderSDO.setReceiveAddressCode(customerAddressSDO.getAddressCode());
                            orderSDO.setAddressCode(customerAddressSDO.getAddressCode());
                            orderSDO.setContactor(customerAddressSDO.getContactName());
                            orderSDO.setContactorPhone(customerAddressSDO.getCellphoneNumber());
                            orderSDO.setBisUnitCode(customerAddressSDO.getOrgBussinessUnitCode());
//                            orderSDO.setProductGroupCode(customerAddressSDO.getItemGroup());
                            //地址
//                            orderSDO.setReceiveDetailAddress(customerAddressSDO.getAddress());
//                            orderSDO.setProductGroupName(customerAddressSDO.getItemGroupName());
                            // 创建人
                            orderSDO.setCreatorId(employeeGetCurrentLoginResponse.getEmployeeId());
                            orderSDO.setCreatorName(employeeGetCurrentLoginResponse.getEmployeeName());
                        }

                    }

                    //查询客户信息
                    if (StringUtils.isNotBlank(orderSDO.getCustomerCode())) {
                        CustomerRequest request = new CustomerRequest();
                        request.setCode(orderSDO.getCustomerCode());
                        Result<CustomerSDO> result = customerQueryService.queryCustomer(request);
                        orderSDO.setCustomerName(result.getResult().getName());
                        orderSDO.setCustomerCode(result.getResult().getCode());

                    }

                    //查询逻辑仓信息
                    if (StringUtils.isNotBlank(importOrderRequests.get(0).getWareHouseCode())) {
                        WmsQueryWarehouseZoneListRequest byIdRequest = new WmsQueryWarehouseZoneListRequest();
                        byIdRequest.setCode(importOrderRequests.get(0).getWareHouseCode());
                        WmsQueryWarehouseZoneListResponse warehouseInfoResult = unifiedInventoryService.wmsQueryWarehouseZoneList(byIdRequest);
                        if (Objects.nonNull(warehouseInfoResult.getResult().get(0))) {
                            orderSDO.setWareHouseName(warehouseInfoResult.getResult().get(0).getName());
                            orderSDO.setWareHouseCode(warehouseInfoResult.getResult().get(0).getId());
                        }
                    }

                    //设置订单标识
                    SetOrderTag.getOrderTag(importOrderRequests.get(0).getOrderType().trim(), orderSDO);
                    String id = orderWriteRepository.saveOrder(orderSDO);

                    //创建销售明细单
                    List<OrderLineSDO> orderLineSDOS = new ArrayList<>();
                    int i = 1;
                    try {
                        for (ImportOrderRequest it : importOrderRequests) {
                            OrderLineSDO orderLineSDO = OrderLineSDO.builder()
                                    //                                .sal(it.getSaleUnit())
                                    .serialNumber(String.valueOf(i * 10))
                                    .status(OrderStatus.BEFORE_SUBMIT.getCode())//待提交
                                    .mainOrderBizId(orderSDO.getOrderBizId())
                                    .remark(it.getOrderLineRemark())
                                    //                                .saleUnit(it.getSaleUnit())
                                    .mainOrderId(id)
                                    .customerCode(orderSDO.getCustomerCode()).build();

                            //
                            String orderTag = orderSDO.getOrderTag();
                            //识别子单标签
                            if (StringUtils.isNotBlank(orderTag)){
                                if (SetOrderTag.EXCHANGE.equals(orderTag)){
                                    orderLineSDO.setOrderLineTag(SetOrderTag.EXCHANGE);
                                }
                                if (SetOrderTag.RETURN.equals(orderTag)){
                                    orderLineSDO.setOrderLineTag(SetOrderTag.RETURN);
                                }
                                if (SetOrderTag.NORMAL.equals(orderTag)){
                                    orderLineSDO.setOrderLineTag(SetOrderTag.NORMAL);
                                }
                            }

//                            Double unitPrice = it.getUnitPrice() == null ? null : (Double.valueOf(it.getUnitPrice()) * 100);
                            Long unitPrice = null;
                            BigDecimal mul = new BigDecimal("100");
                            if (it.getUnitPrice() != null) {
                                BigDecimal price = new BigDecimal(it.getUnitPrice());
                                unitPrice = price.multiply(mul).longValue();
                            }

                            ScItemSDO scItemSDO = ScItemSDO.builder()
                                    .scItemId(it.getScItecmId())
                                    .unitPrice(unitPrice)
                                    .quantity(Integer.parseInt(it.getQuantity()))
                                    .saleUnit(it.getSaleUnit()).build();

                            i++;

                            orderLineSDO.setScItemSDO(scItemSDO);

                            SearchScItemRequest searchScItemRequest = new SearchScItemRequest();
                            SearchReqDTO searchReqDTO = new SearchReqDTO();
                            List<String> list = new ArrayList<>();
                            list.add(orderLineSDO.getScItemSDO().getScItemId());
                            searchReqDTO.setOuterIdList(list);
                            searchScItemRequest.setSearchReqDTO(searchReqDTO);


                            //查询货品信息
                            Result<List<com.epoch.app.bcots.model.dto.ScItemSDO>> listResult = baseDataService.searchScItem(searchScItemRequest);
                            if (listResult.isSuccess() && CollectionUtils.isNotEmpty(listResult.getResult())) {
                                scItemSDO.setScItemTitle(listResult.getResult().get(0).getTitle());
                                scItemSDO.setScItemId(listResult.getResult().get(0).getScItemId());
                                //                            scItemSDO.setUnit(listResult.getResult().get(0).getUnit());
                            }
                            //库存单位
                            String inventoryUnit = String.valueOf(listResult.getResult().get(0).getFeatures().get("unitName"));
                            QuerySaleOrderLine line = new QuerySaleOrderLine();
                            line.setGoodsId(scItemSDO.getScItemId());
                            line.setGoodsName(scItemSDO.getScItemTitle());
                            line.setQuantity(String.valueOf(scItemSDO.getQuantity()));
                            // 填写以填写为准，否则系统默认库存单位
                            line.setSaleUnit(StringUtils.isBlank(scItemSDO.getSaleUnit()) ?  inventoryUnit: scItemSDO.getSaleUnit());
                            //                        line.setRemark();
                            //                        line.setUnitPrice();
                            //                        line.setSaleUnitList();
                            //                        line.setSaleUnitName();
                            line.setInventoryUnit(String.valueOf(listResult.getResult().get(0).getFeatures().get("unit")));
                            line.setInventoryUnitCode(String.valueOf(listResult.getResult().get(0).getFeatures().get("unitName")));
                            //                        line.setUnitConvert();
                            QuerySaleOrderLineRequest request = new QuerySaleOrderLineRequest();
                            request.setId(id);
                            request.setSaleOrderLines(Collections.singletonList(line));

                            List<QuerySaleOrderLine> querySaleOrderLines = orderLineQueryServiceRepository.queryScItemInfo(request);

                            // 查询 商品转换关系
                            QuerySaleUnitRequest querySaleUnitRequest = QuerySaleUnitRequest.builder().scItemId(scItemSDO.getScItemId()).build();
                            querySaleUnitRequest.setInventoryUnit(String.valueOf(listResult.getResult().get(0).getFeatures().get("unit")));
                            querySaleUnitRequest.setInventoryUnitCode(String.valueOf(listResult.getResult().get(0).getFeatures().get("unitName")));
                            querySaleUnitRequest.setUnitConvert("1");
                            Result<List<SelectCombox>> querySaleUnitList = forecastOrderLineQueryService.querySaleUnitList(querySaleUnitRequest);
                            List<SelectCombox> saleUnitListResult = querySaleUnitList.getResult();
                            Map<String, SelectCombox> unitMap = new HashMap<>();
                            Nullable.stream(saleUnitListResult).forEach(t -> {
                                unitMap.put(t.getValue(), t);
                            });

                            SelectCombox selected = new SelectCombox();
                            if (StringUtils.isNotBlank(scItemSDO.getSaleUnit())) {
                                selected = unitMap.get(scItemSDO.getSaleUnit());
                            }else{
                                selected = unitMap.get(inventoryUnit);
                            }

                            if (selected != null) {
                                scItemSDO.setUnitConvert(selected.getExt());
                            }

                            if (CollectionUtils.isNotEmpty(querySaleOrderLines) && null != querySaleOrderLines.get(0)) {
                                scItemSDO.setScItemId(querySaleOrderLines.get(0).getGoodsId());
                                scItemSDO.setScItemTitle(querySaleOrderLines.get(0).getGoodsName());
                                scItemSDO.setScItemOutCode(it.getScItecmId());
                                if (null != querySaleOrderLines.get(0).getUnitConvert()) {
                                    scItemSDO.setUnitChangeRelation(String.valueOf(querySaleOrderLines.get(0).getUnitConvert()));
                                }
                                scItemSDO.setInventoryUnitCode(querySaleOrderLines.get(0).getInventoryUnitCode());
                                scItemSDO.setInventoryUnitName(querySaleOrderLines.get(0).getInventoryUnit());
                                if (scItemSDO.getUnitPrice() == null) {
                                    scItemSDO.setUnitPrice(querySaleOrderLines.get(0).getUnitPrice() == null ? null : Long.valueOf(querySaleOrderLines.get(0).getUnitPrice()));
                                }

                                if (SaleOrderTag.CASH_ORDER.getCode().equals(orderSDO.getOrderType()) || SaleOrderTag.STD_RETURN_ORDER.getCode().equals(orderSDO.getOrderType())) {
                                    Map<String, String> features = new HashMap<>();
                                    if (null != unitPrice) {
                                        //手工单价
                                        BigDecimal bUnitPrice = new BigDecimal(unitPrice);
                                        features.put(SaleOrderConstants.MANUAL_PRICE, String.valueOf(unitPrice));
                                        //常规单价
                                        scItemSDO.setUnitPrice(querySaleOrderLines.get(0).getUnitPrice() == null ? null : Long.valueOf(querySaleOrderLines.get(0).getUnitPrice()));
                                        if (null != scItemSDO.getQuantity()) {
                                            //手工总金额
                                            BigDecimal bQuantity = new BigDecimal(scItemSDO.getQuantity());
                                            Long manualTotalAmount = bUnitPrice.multiply(bQuantity).longValue();
                                            features.put(SaleOrderConstants.MANUAL_TOTAL_AMOUNT, String.valueOf(manualTotalAmount));
                                        }
                                    }

                                    if (MapUtils.isEmpty(orderLineSDO.getFeatures())) {
                                        orderLineSDO.setFeatures(features);
                                    } else {
                                        orderLineSDO.getFeatures().putAll(features);
                                    }

                                }

                                scItemSDO.setCategoryCode(querySaleOrderLines.get(0).getCategoryCode());
                                scItemSDO.setCategoryDesc(querySaleOrderLines.get(0).getCategoryDesc());
                                scItemSDO.setCategoryChildCode(querySaleOrderLines.get(0).getCategoryChildCode());
                                scItemSDO.setCategoryChildDesc(querySaleOrderLines.get(0).getCategoryChildDesc());

                                scItemSDO.setFirstCategoryCode(querySaleOrderLines.get(0).getFirstCategoryCode());
                                scItemSDO.setFirstCategoryDesc(querySaleOrderLines.get(0).getFirstCategoryDesc());
                                scItemSDO.setSecondCategoryCode(querySaleOrderLines.get(0).getSecondCategoryCode());
                                scItemSDO.setSecondCategoryDesc(querySaleOrderLines.get(0).getSecondCategoryDesc());


                                orderLineSDO.setScItemSDO(scItemSDO);
                                //创建销售子订单
                                orderLineWriteRepository.save(orderLineSDO);
                            }
                            orderLineSDOS.add(orderLineSDO);
                            saveSuccessList.add(it);

                        }
                    } catch (Exception e) {
//                        if (id != null) {
//                            orderWriteRepository.deleteOrder(id);
//                        }
                        importOrderRequests.stream().forEach(importOrderRequest -> {
                            importOrderRequest.setErrorMessage("创建销售订单失败");
                            errorList.add(importOrderRequest);
                        });
                    }


                    OrderQueryRequest orderQueryRequest = new OrderQueryRequest();
                    orderQueryRequest.setId(id);
                    OrderQueryResponse response = orderQueryServiceRepository.query(orderQueryRequest);
                    if (Objects.nonNull(response) && StringUtils.isNotBlank(response.getId())) {
                        OrderSDO finalOrderSDO = SaveOrderConverter.respConverterSDO(response);

                        //记录创建操作日志
                        recordOperationLog(finalOrderSDO, OrderOperateType.CREATE.getDesc(), employeeGetCurrentLoginResponse);

                        OrderWriteEntity orderWriteEntity = OrderWriteFactory.updateOrder(finalOrderSDO);
                        orderWriteEntity.submit();

                        //记录提交操作日志
                        recordOperationLog(finalOrderSDO, OrderOperateType.SUBMIT.getDesc(), employeeGetCurrentLoginResponse);
                    }

                }
            }
        }
        //失败的条数
        Nullable.stream(errorList).forEach(resultList::add);

        //成功的条数
        Nullable.stream(saveSuccessList).forEach(resultList::add);

        Map<String, String> errorMessageMap = new HashMap<>();
        resultList.stream().forEach(importOrderRequest -> errorMessageMap.put(importOrderRequest.getCustomerReferenceNo(), importOrderRequest.getErrorMessage()));
        // 按照导入 原顺序排序
        resultList = Nullable.stream(importOrderList).map(it -> {
            it.setErrorMessage(errorMessageMap.get(it.getCustomerReferenceNo()));
            return it;
        }).collect(Collectors.toList());

        return Result.success(resultList);
    }

    private void recordOperationLog(OrderSDO orderSDO, String desc, EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse) {
        OpLogModel.OpLogModelBuilder<String> builder = OpLogModel.builder();
        OpLogModel<String> opLogModel = builder.build();
        opLogModel.setModuleName(ModuleEnum.SALES.getModuleName());
        opLogModel.setModuleId(String.valueOf(ModuleEnum.SALES.getModuleId()));
        opLogModel.setObjectId(orderSDO.getId());
        opLogModel.setObjectName("id");
        opLogModel.setOperateType(OperateType.EDIT.getOperateType());
        opLogModel.setOperatorType(OperatorType.USER.getOperatorType());
        opLogModel.setOldValue(JSONObject.toJSONString(orderSDO));
        Map<String, String> map = new HashMap<>();
        if (Objects.nonNull(employeeGetCurrentLoginResponse)) {
            map.put("name", employeeGetCurrentLoginResponse.getEmployeeName());
        }
        map.put("active", desc);
        String logInfo = JSONObject.toJSONString(map);
        opLogModel.setFeatures(logInfo);
        opLogModel.setNewValue(JSONObject.toJSONString(queryOrderSDO(orderSDO.getId())));
        log.asyncMonitorObjectChangeV2(opLogModel);
    }


    private Boolean checkOrderType(String orderTag, ImportOrderRequest importOrderRequest) {
        if (orderTag.equals(SetOrderTag.NORMAL)) {
            Map<String, String> normalMap = new HashMap<>();
            normalMap.put(SaleOrderTag.STD_ORDER.getCode(), SaleOrderTag.STD_ORDER.getCode());
            normalMap.put(SaleOrderTag.REPLENISH_ORDER.getCode(), SaleOrderTag.REPLENISH_ORDER.getCode());
            normalMap.put(SaleOrderTag.FREE_ORDER.getCode(), SaleOrderTag.FREE_ORDER.getCode());
            normalMap.put(SaleOrderTag.CAR_ORDER.getCode(), SaleOrderTag.CAR_ORDER.getCode());
            normalMap.put(SaleOrderTag.CASH_ORDER.getCode(), SaleOrderTag.CASH_ORDER.getCode());

            List<ImportOrderRequest> normalList = new ArrayList<>();

            for (String key : normalMap.keySet()) {
                if (key.equals(importOrderRequest.getOrderType())) {
                    normalList.add(importOrderRequest);
                }
            }
            if (CollectionUtils.isEmpty(normalList)) {
                return false;
            }
        }
        if (orderTag.equals(SetOrderTag.RETURN)) {
            Map<String, String> returnMap = new HashMap<>();
            returnMap.put(SaleOrderTag.LOGISTIC_RETURN_ORDER.getCode(), SaleOrderTag.LOGISTIC_RETURN_ORDER.getCode());
            returnMap.put(SaleOrderTag.STD_RETURN_ORDER.getCode(), SaleOrderTag.STD_RETURN_ORDER.getCode());

            List<ImportOrderRequest> returnList = new ArrayList<>();


            for (String key : returnMap.keySet()) {
                if (key.equals(importOrderRequest.getOrderType())) {
                    returnList.add(importOrderRequest);
                }
            }
            if (CollectionUtils.isEmpty(returnList)) {
                return false;
            }
        }
        if (orderTag.equals(SetOrderTag.EXCHANGE)) {
            if (!importOrderRequest.getOrderType().equals(SaleOrderTag.EXCHANGE_ORDER.getCode())) {
                return false;
            }
        }

        return true;

    }


    private ImportOrderRequest excelCheckStock(ImportOrderRequest importOrderRequest) {

        //逻辑仓ID
        String warehouseId = null;
        //查询逻辑仓信息
        if (StringUtils.isNotBlank(importOrderRequest.getWareHouseCode())) {
            WmsQueryWarehouseZoneListRequest byIdRequest = new WmsQueryWarehouseZoneListRequest();
            byIdRequest.setCode(importOrderRequest.getWareHouseCode());
            WmsQueryWarehouseZoneListResponse warehouseInfoResult = unifiedInventoryService.wmsQueryWarehouseZoneList(byIdRequest);
            if (CollectionUtils.isNotEmpty(warehouseInfoResult.getResult()) && Objects.nonNull(warehouseInfoResult.getResult().get(0))) {
                warehouseId = warehouseInfoResult.getResult().get(0).getId();
            }
        }


        //查询货品信息
        SearchScItemRequest searchScItemRequest = new SearchScItemRequest();
        SearchReqDTO searchReqDTO = new SearchReqDTO();
        List<String> list = new ArrayList<>();
        if (StringUtils.isNotBlank(importOrderRequest.getScItecmId())) {
            list.add(importOrderRequest.getScItecmId());
            searchReqDTO.setOuterIdList(list);
        }
        searchScItemRequest.setSearchReqDTO(searchReqDTO);
        Result<List<com.epoch.app.bcots.model.dto.ScItemSDO>> listResult = baseDataService.searchScItem(searchScItemRequest);
        if (Objects.isNull(listResult.getResult().get(0))) {
            importOrderRequest.setErrorMessage("未查到对应货品信息");
        } else {
            //校验库存
            GetListWarehouseStockRequest getRequest = new GetListWarehouseStockRequest();
            getRequest.setWarehouseAreaId(warehouseId);
            getRequest.setType("1");
            String scItemId = listResult.getResult().get(0).getScItemId();
            getRequest.setGoodsId(scItemId);
            Result<List<WarehouseInventory>> listWarehouseStock = otsUnifiedInventoryService.getListWarehouseStock(getRequest);
            if (CollectionUtils.isEmpty(listWarehouseStock.getResult())) {
                importOrderRequest.setErrorMessage("仓库中未查到对应货品");
            } else {
                WarehouseInventory warehouseInventory = listWarehouseStock.getResult().get(0);
                Integer quantity = Integer.valueOf(importOrderRequest.getQuantity());
                if (null == warehouseInventory.getAvailableQuantity() || quantity > warehouseInventory.getAvailableQuantity()) {
                    importOrderRequest.setErrorMessage("库存不足");
                }
            }
        }

        return importOrderRequest;
    }

    public OrderSDO queryOrderSDO(String id) {
        OrderQueryRequest request = new OrderQueryRequest();
        request.setId(id);
        return orderQueryServiceRepository.querySingle(request);
    }

    /**
     * 获取 登录人 所属销售组织code
     *
     * @param type
     * @return
     */
    private List<OrganizationSDO> getLoginOrganizationCode(Integer type) {
        GetLoginEmployOrganizationPermissionsRequest request = GetLoginEmployOrganizationPermissionsRequest.builder().type(type).build();
        Result<List<OrganizationSDO>> loginEmployOrganizationPermissions = otsPlatformEnhanceService.getLoginEmployOrganizationPermissions(request);
        if (ObjectUtils.isEmpty(loginEmployOrganizationPermissions)) {
            return new ArrayList<>();
        }
        List<OrganizationSDO> result = loginEmployOrganizationPermissions.getResult();
        if (CollectionUtils.isEmpty(result)) {
            return new ArrayList<>();
        }
        return result;
    }

    /**
     * 查询 销售组织的 业务渠道
     *
     * @param ids
     * @return
     */
    private List<String> businessChannelCodes(List<String> ids) {
        GetOrgChannelRelationByOrgId2Request request = GetOrgChannelRelationByOrgId2Request.builder().ids(ids).build();
        Result<List<OrganizationChannelRelationSDO>> orgChannelRelationByOrgId2 = otsPlatformEnhanceService.getOrgChannelRelationByOrgId2(request);
        if (ObjectUtils.isEmpty(orgChannelRelationByOrgId2)) {
            return new ArrayList<>();
        }
        List<OrganizationChannelRelationSDO> result = orgChannelRelationByOrgId2.getResult();
        if (CollectionUtils.isEmpty(result)) {
            return new ArrayList<>();
        }
        return result.stream().map(OrganizationChannelRelationSDO::getOutCode).collect(Collectors.toList());
    }

    /**
     * 获取登录人 负责的收货地址code
     *
     * @param addressCode                     所有 需要校验的code
     * @param employeeGetCurrentLoginResponse 登陆人
     * @return 符合要求的code
     */
    private Map<String, List<CustomerAddressSDO>> addressLists(List<String> addressCode, EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse) {

        CustomerAddressBatchRequest addressBatchRequest = CustomerAddressBatchRequest.builder().addressCodes(addressCode).build();

        String relatedOrganizationId = employeeGetCurrentLoginResponse.getRelatedOrganizationId();
        switch (employeeGetCurrentLoginResponse.getRelatedOrganizationType()) {
            case "103":
                // 分子公司
                addressBatchRequest.setOrgBussinessUnitCode(relatedOrganizationId);
                break;
            case "104":
                // 销售组织
                addressBatchRequest.setOrgSaleOrganizationCode(relatedOrganizationId);
                break;
            case "105":
                // 销售渠道
                addressBatchRequest.setOrgSaleChannelCode(relatedOrganizationId);
                break;
            case "106":
                // 销售部门
                addressBatchRequest.setOrgSaleDepartmentCode(relatedOrganizationId);
                break;
        }

        Result<List<CustomerAddressSDO>> listResult = customerAddressQueryService.batchQueryCustomerAddress(addressBatchRequest);
        List<CustomerAddressSDO> result = CollectionUtils.isEmpty(listResult.getResult()) ? new ArrayList<>() : listResult.getResult();
        Map<String, List<CustomerAddressSDO>> collect = result.stream().collect(Collectors.groupingBy(CustomerAddressSDO::getAddressCode));

        return collect;
    }

    /**
     * 登录人导入 权限校验
     *
     * @param importOrderRequest
     * @param loginOrganizationCode
     * @param channelCode
     * @param warehouseCodes
     * @param addressCodes
     * @return
     */
    private String importCheckErrorMessage(ImportOrderRequest importOrderRequest,
                                           List<String> loginOrganizationCode,
                                           List<String> channelCode,
                                           List<String> warehouseCodes,
                                           List<String> addressCodes) {
        if (StringUtils.isBlank(importOrderRequest.getCustomerReferenceNo())) {
            return "客户参考号不能为空";
        } else {
            importOrderRequest.setCustomerReferenceNo(importOrderRequest.getCustomerReferenceNo().trim());
            if (importOrderRequest.getCustomerReferenceNo().contains(" ")
                    || PATTERN_SPECIAL_STRING.matcher(importOrderRequest.getCustomerReferenceNo()).matches()) {
                return "客户参考号不能有特殊字符";
            }
        }
        if (StringUtils.isBlank(importOrderRequest.getOrderType().trim())) {
            return "销售订单类型不能为空";
        } else {
            importOrderRequest.setOrderType(importOrderRequest.getOrderType().trim());
            if (importOrderRequest.getOrderType().contains(" ")
                    || PATTERN_SPECIAL_STRING.matcher(importOrderRequest.getOrderType()).matches()) {
                return "销售订单类型不能有特殊字符";
            }
        }

        if (StringUtils.isBlank(importOrderRequest.getOrganizationCode())) {
            return "销售组织不能为空";
        } else {
            importOrderRequest.setOrganizationCode(importOrderRequest.getOrganizationCode().trim());
            if (importOrderRequest.getOrganizationCode().contains(" ")
                    || PATTERN_SPECIAL_STRING.matcher(importOrderRequest.getOrganizationCode()).matches()) {
                return "销售组织不能有特殊字符";
            }
        }
        if (StringUtils.isBlank(importOrderRequest.getChannelCode())) {
            return "业务渠道不能为空";
        } else {
            importOrderRequest.setChannelCode(importOrderRequest.getChannelCode().trim());
            if (importOrderRequest.getChannelCode().contains(" ")
                    || PATTERN_SPECIAL_STRING.matcher(importOrderRequest.getChannelCode()).matches()) {
                return "业务渠道不能有特殊字符";
            }
        }
        if (StringUtils.isBlank(importOrderRequest.getReceiveAddressCode())) {
            return "收货地址不能为空";
        } else {
            importOrderRequest.setReceiveAddressCode(importOrderRequest.getReceiveAddressCode().trim());
            if (importOrderRequest.getReceiveAddressCode().contains(" ")
                    || PATTERN_SPECIAL_STRING.matcher(importOrderRequest.getReceiveAddressCode()).matches()) {
                return "收货地址不能有特殊字符";
            }
        }
        if (StringUtils.isBlank(importOrderRequest.getWareHouseCode())) {
            return "发货仓不能为空";
        } else {
            importOrderRequest.setWareHouseCode(importOrderRequest.getWareHouseCode().trim());
            if (importOrderRequest.getWareHouseCode().contains(" ")
                    || PATTERN_SPECIAL_STRING.matcher(importOrderRequest.getWareHouseCode()).matches()) {
                return "发货仓不能有特殊字符";
            }
        }
        if (StringUtils.isBlank(importOrderRequest.getQuantity()) || !StringUtils.isNumeric(importOrderRequest.getQuantity())) {
            return "数量无效";
        } else {
            importOrderRequest.setQuantity(importOrderRequest.getQuantity().trim());
            if (importOrderRequest.getQuantity().contains(" ")
                    || PATTERN_SPECIAL_STRING.matcher(importOrderRequest.getQuantity()).matches()) {
                return "数量不能有特殊字符";
            }
        }
        // 订单类型编码：
        //ZOR2：标准销售订单
        //ZFD2：免费销售订单
        //ZBV：现金销售订单
        //ZRE2：标准退货订单
        // 成本中心 免费订单类型必填
        if (SaleOrderTag.FREE_ORDER.getCode().equals(importOrderRequest.getOrderType())) {
            if (StringUtils.isBlank(importOrderRequest.getCostCenter())) {
                return "免费订单 成本中心不能为空";
            } else {
                importOrderRequest.setCostCenter(importOrderRequest.getCostCenter().trim());
                if (importOrderRequest.getCostCenter().contains(" ")
                        || PATTERN_SPECIAL_STRING.matcher(importOrderRequest.getCostCenter()).matches()) {
                    return "免费订单 成本中心不能有特殊字符";
                }
            }
        }
        // 现金客户名称 现金订单类型必填
        if (SaleOrderTag.CASH_ORDER.getCode().equals(importOrderRequest.getOrderType())) {
            if (StringUtils.isBlank(importOrderRequest.getCashCustomerName())) {
                return "现金订单 成现金客户名称不能为空";
            } else {
                importOrderRequest.setCashCustomerName(importOrderRequest.getCashCustomerName().trim());
                if (importOrderRequest.getCashCustomerName().contains(" ")
                        || PATTERN_SPECIAL_STRING.matcher(importOrderRequest.getCashCustomerName()).matches()) {
                    return "现金订单 成现金客户名称不能有特殊字符";
                }
            }
        }
        // 单价 退货订单&现金订单必填
        boolean priceBoolean = SaleOrderTag.CASH_ORDER.getCode().equals(importOrderRequest.getOrderType()) || SaleOrderTag.STD_RETURN_ORDER.getCode().equals(importOrderRequest.getOrderType().trim());
        if (priceBoolean && StringUtils.isBlank(importOrderRequest.getUnitPrice())) {
            return "退货订单&现金订单 单价不能为空";
        } else {
            if (StringUtils.isNotBlank(importOrderRequest.getUnitPrice()) && !PATTERN_NUMERIC.matcher(importOrderRequest.getUnitPrice()).matches()) {
                return "单价无效";
            }
        }
        // 标准退货 订单原因必须输入
        if (SaleOrderTag.STD_RETURN_ORDER.getCode().equals(importOrderRequest.getOrderType())) {
            if (StringUtils.isBlank(importOrderRequest.getCreateReason())) {
                return "标准退货订单 单据原因不能为空";
            } else {
                importOrderRequest.setCreateReason(importOrderRequest.getCreateReason().trim());
                if (importOrderRequest.getCreateReason().contains(" ")
                        || PATTERN_SPECIAL_STRING.matcher(importOrderRequest.getCreateReason()).matches()) {
                    return "标准退货订单 单据原因不能有特殊字符";
                }
            }
        }

        //校验主单备注信息   长度小于等于50
        if (StringUtils.isNotBlank(importOrderRequest.getOrderRemark()) && importOrderRequest.getOrderRemark().length() > 256) {
            return "主单备注信息长度不能超过255个字";
        }
        //校验子单备注信息   长度小于等于50
        if (StringUtils.isNotBlank(importOrderRequest.getOrderLineRemark()) && importOrderRequest.getOrderLineRemark().length() >256) {
            return "子单备注详情信息长度不能超过255个字";
        }

        // 校验 导入数据 不是登陆人所属销售组织 不允许导入
        if (!loginOrganizationCode.contains(importOrderRequest.getOrganizationCode())) {
            return "销售组织没有权限";
        }
        // 校验 导入数据 不是登陆人所属销售渠道 不允许导入
        if (!channelCode.contains(importOrderRequest.getChannelCode())) {
            return "业务渠道没有权限";
        }
        // 校验 导入数据 不是登陆人所管理客户地址 不允许导入
        if (!addressCodes.contains(importOrderRequest.getReceiveAddressCode())) {
            return "收货地址没有权限";
        }
        // 校验 导入数据 不是登陆人所管理仓库 不允许导入
        if (!warehouseCodes.contains(importOrderRequest.getWareHouseCode())) {
            return "发货仓没有权限";
        }

        // 导入 的业务渠道 和客户 不一致 也不能导入
        QueryAddressRequest queryAddressRequest = new QueryAddressRequest();
        queryAddressRequest.setAddressCode(importOrderRequest.getReceiveAddressCode());
        queryAddressRequest.setChannelCode(importOrderRequest.getChannelCode());
        Result<List<CustomerAddressSDO>> listResult = customerAddressQueryService.pageQueryCustomerAddress(queryAddressRequest);
        if (ObjectUtils.isEmpty(listResult)) {
            return "业务渠道 和客户不一致";
        }
        if (CollectionUtils.isEmpty(listResult.getResult())) {
            return "业务渠道 和客户不一致";
        }
        List<CustomerAddressSDO> collect = listResult.getResult().stream().filter(customerAddressSDO ->
                StringUtils.isNotBlank(customerAddressSDO.getPrincipalName())
        ).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(collect) || Objects.isNull(collect.get(0))) {
            return "客户收获地址未匹配到 对应的负责人";
        }

        return null;
    }

    /**
     * 校验 商品 是否可用
     *
     * @param outerId
     * @return
     */
    private Boolean checkScItemStatus(String outerId) {
        SearchScItemRequest searchScItemRequest = new SearchScItemRequest();
        SearchReqDTO searchReqDTO = new SearchReqDTO();
        List<String> list = new ArrayList<>();
        list.add(outerId);
        searchReqDTO.setOuterIdList(list);
        searchScItemRequest.setSearchReqDTO(searchReqDTO);
        //查询货品信息
        Result<List<com.epoch.app.bcots.model.dto.ScItemSDO>> listResult = baseDataService.searchScItem(searchScItemRequest);
        if (ObjectUtils.isEmpty(listResult.getResult())) {
            return null;
        }
        List<com.epoch.app.bcots.model.dto.ScItemSDO> result = listResult.getResult();
        if (CollectionUtils.isEmpty(result)) {
            return null;
        }
        return result.get(0).getStatus() == 1 ? true : false;
    }

    /**
     * 查询登录人 的 仓库权限
     *
     * @return
     */
    private List<String> getWarehouseCodes() {
        QueryCargoZoneListWithAccessRequest cargoZoneListRequest =
                QueryCargoZoneListWithAccessRequest.builder()
                        .model(3)
                        .typeList(Stream.of(1, 2, 3, 4, 5).collect(Collectors.toList()))
                        .build();
        // 获取登陆人 仓库权限
        QueryCargoZoneListWithAccessResponse searchCargoZoneListForPageResponse = bcOtsService.queryCargoZoneListWithAccess(cargoZoneListRequest);
        if (ObjectUtils.isEmpty(searchCargoZoneListForPageResponse)) {
            return new ArrayList<>();
        }
        List<WarehouseInfo> result = searchCargoZoneListForPageResponse.getResult();
        if (CollectionUtils.isEmpty(result)) {
            return new ArrayList<>();
        }
        return result.stream().map(WarehouseInfo::getCode).collect(Collectors.toList());

    }

    /**
     * 设置信贷检查情况
     *
     * @param features
     * @param creditCheckStatus
     */
    private void setCreditCheck(Map<String, String> features, String creditCheckStatus) {
//        String checkStatusName = "信贷检查未执行/状态未设置";
        String checkStatusName = "未执行信贷";
        if (StringUtils.isNotEmpty(creditCheckStatus)) {
            features.put(SaleOrderConstants.CREDIT_CHECK_STATUS, creditCheckStatus);
            if ("A".equals(creditCheckStatus)) {
//                checkStatusName = "信用检查已完成,单据完备";
                checkStatusName = "已同意";
            } else if ("B".equals(creditCheckStatus)) {
//                checkStatusName = "信用检查已完成,单据不完备";
                checkStatusName = "信贷冻结";
            } else if ("C".equals(creditCheckStatus)) {
//                checkStatusName = "信用检查已完成,单据不完备,部分批准";
                checkStatusName = "信贷部分批准";
            } else if ("D".equals(creditCheckStatus)) {
                checkStatusName = "信贷批准";
            } else {
                checkStatusName = creditCheckStatus;
            }
        }
        features.put(SaleOrderConstants.CREDIT_CHECK_STATUS_NAME, checkStatusName);
    }

}

